Skip to content

Week 5 Lecture 1

Property-Based Testing

Abstract data types

  • Not to be confused with algebraic data types
  • Fields not defined, functions only has the synopsis.
Only the boxes, don’t look at the spaghetti in it 📦️

An ADT consists of:

  1. an interface containing types and operations
  2. specification (what they do, what properties they have)
  3. examples illustrating correct and incorrect use

One ADT impl consists of:

  1. definition of the previously declared functions
  2. evidence that the stated properties hold

Nowadays the evidence can be a formal proof, but it could also be empirical testing ⇒ property based testing!!!

What to do when inconsistency is found

  1. Change to code to fit the specification

    • triv
  2. Change the specification to better fit to code

    • needs negotiation since it affects the user code
  3. Change both
Common issue: most modules are underspecified so the user can get into underspecified behavior of the implementation. These are usually hard-to-detekkt and hard-to-localize

Properties that we can test:

  1. Algebraic laws

    • similar to monad laws

      • associativity (x <> y) <> z = x <> (y <> z)
      • commutativity x <> y = y <> x
      • idempotence x <> x = x
      • identity element x <> mempty = x, mempty <> x = x
  2. Invariants

    • properties that must hold even after the operation

      • sorted xs => sorted (insert x xs)
  3. Round-trip (inverse) properties

    • pair of function that ‘undo’ each other

      • parse (print e) == e
      • decode (encode x) == x

We can create tests by input partitioning:

  • breaking the input set into equivalence classes
  • find elements and boundary values from each equivalence class
  • For example:

    • int: negative numbers, positive numbers, {0}

      • values: min int, −10, −1, 0, 1, 123, max int
    • float: IEEE 754 floating-points