$30 off During Our Annual Pro Sale. View Details »

Property Based Testing

Property Based Testing

5min lightning talk for the SoCraTes Belgium meetup and CukeUp London.

Mathias Verraes

April 06, 2016
Tweet

More Decks by Mathias Verraes

Other Decks in Technology

Transcript

  1. -- Tests double 1 `should_be` 2 double 2 `should_be` 4

    -- Implementation double x | x == 1 = 2 | x == 2 = 4
  2. quickCheck double_is_always_even Passed: 0 Passed: 1 Passed: -3 Passed: -1

    (...) Passed: -58 Passed: 89 +++ OK, passed 100 tests.
  3. More properties of double double_compare_to_input x | x > 0

    = double x > x | x < 0 = double x < x | x == 0 = True double_minus_input x = double x - x == x
  4. > quickCheck reverse_is_distributive Passed: [] [] Passed: [] [1] Passed:

    [1] [] Failed: [3,-3] [0,2,0] Passed: [] [0,2,0] Failed: [3] [0,2,0] Failed: [-3] [0,2,0] Failed: [0] [0,2,0] Failed: [0] [2,0] (...) Falsifiable (after 4 tests and 6 shrinks): [0] [1]
  5. Passed: [] [] Passed: [1,-2] [0] Passed: [-2] [] (...)

    Passed: [-34,44,-58,-41,-17,-53,-14,27,54,46,-10,-46,-20,46] [-9,-32,-47,50,43,-47,-43,-61,37,4,-59,48,34] +++ OK, passed 100 tests.
  6. Split 1 -- define split :: Char -> String ->

    [String] -- so that split '@' "[email protected]" == ["foo","example.com"] split '/' "/usr/include" == ["", "usr", "include"] 1 https://www.schoolofhaskell.com/user/pbv/an-introduction-to-quickcheck-testing
  7. -- splitting an empty list results in an empty list

    split char [] = [] split char str | null after = before : [] | otherwise = before : split char (tail after) where before = takeWhile (/=char) str after = dropWhile (/=char) str
  8. Property: Splitting and unsplitting -- test unsplit '@' ["foo","example.com"] ==

    "[email protected]" unsplit '/' ["", "usr", "include"] == "/usr/include" --implementation unsplit :: Char -> [String] -> String unsplit char = concat . intersperse [char]
  9. > quickCheck unsplit_inverses_split Passed: "" Passed: "\252\210" '\252' Passed: "\163^\EOT"

    '\163' Passed: "v\RSs" 'v' Failed: "y" 'y' Failed: "a" 'a' Falsifiable (after 6 tests and 1 shrink): "a" 'a'
  10. split 'a' "a" == [""] unsplit 'a' [""] == ""

    -- should be: split 'a' "a" == ["", ""] unsplit 'a' ["", ""] == "a"
  11. Modify the definition of split split char [] = []

    ... -- becomes split char [] = [""] ... > quickCheck unsplit_inverses_split +++ OK, passed 100 tests.
  12. Property Based Testing → test lots of random cases cheaply

    → encourage thinking about general properties Thanks :-) @mathiasverraes