Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Check Your Work: An Introduction to Property-Ba...

Avatar for Connor Mendenhall Connor Mendenhall
August 04, 2016
30

Check Your Work: An Introduction to Property-Based Testing

Avatar for Connor Mendenhall

Connor Mendenhall

August 04, 2016
Tweet

Transcript

  1. Properties “add(a,b) equals a+b for all values of a and

    b” “sort(list) returns all values in list in ascending order.” “Model.save() is idempotent.”
  2. Prime factors 4 = 2·2 17 = 17 30 =

    2·3·5 31878 = 2·3·3·7·11·23
  3. Prime factors 4 = 2·2 17 = 17 30 =

    2·3·5 31878 = 2·3·3·7·11·23
  4. Prime factors 4 = 2·2 17 = 17 30 =

    2·3·5 31878 = 2·3·3·7·11·23
  5. Prime factors 4 = 2·2 17 = 17 30 =

    2·3·5 31878 = 2·3·3·7·11·23
  6. Prime factors user=> (prime-factors 4) [2 2] user=> (prime-factors 17)

    [17] user=> (prime-factors 30) [2 3 5] user=> (prime-factors 31878) [2 3 3 7 11 23]
  7. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  8. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  9. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  10. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  11. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  12. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  13. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  14. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  15. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  16. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  17. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  18. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  19. (defn trial-division [n divisor factors] (if (< n 2) factors

    (if (= 0 (mod n divisor)) (recur (/ n divisor) divisor (conj factors divisor)) (recur n (inc divisor) factors)))) (defn prime-factors [n] (trial-division n 2 []))
  20. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  21. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  22. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  23. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  24. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  25. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  26. (def primes (load-primes "primes.txt")) (defspec primes-have-one-prime-factor 1000 (testing "A prime's

    only prime factor is itself" (prop/for-all [prime (gen/elements primes)] (= [prime] (prime-factors prime)))))
  27. (deftest test-factors-of-two (testing "returns [2 2] for 4" (is (=

    [2 2] (prime-factors 4))))) (defspec two-times-prime-returns-two-and-prime 1000 (testing "Factors of 2 * prime = 2 and the prime" (prop/for-all [prime (gen/elements primes)] (= [2 prime] (prime-factors (* 2 prime))))))
  28. (deftest test-factors-of-two (testing "returns [2 2] for 4" (is (=

    [2 2] (prime-factors 4))))) (defspec two-times-prime-returns-two-and-prime 1000 (testing "Factors of 2 * prime = 2 and the prime" (prop/for-all [prime (gen/elements primes)] (= [2 prime] (prime-factors (* 2 prime))))))
  29. (deftest test-factors-of-two (testing "returns [2 2] for 4" (is (=

    [2 2] (prime-factors 4))))) (defspec two-times-prime-returns-two-and-prime 1000 (testing "Factors of 2 * prime = 2 and the prime" (prop/for-all [prime (gen/elements primes)] (= [2 prime] (prime-factors (* 2 prime))))))
  30. (deftest test-factors-of-nine (testing "returns [3 3] for 9" (is (=

    [3 3] (prime-factors 9))))) (defspec check-prime-times-prime-has-two-prime-factors 1000 (testing "Factoring prime * prime returns both primes" (prop/for-all [prime-one (gen/elements primes) prime-two (gen/elements primes)] (= (set [prime-one prime-two]) (set (prime-factors (* prime-one prime-two)))))))
  31. (deftest test-factors-of-nine (testing "returns [3 3] for 9" (is (=

    [3 3] (prime-factors 9))))) (defspec check-prime-times-prime-has-two-prime-factors 1000 (testing "Factoring prime * prime returns both primes" (prop/for-all [prime-one (gen/elements primes) prime-two (gen/elements primes)] (= (set [prime-one prime-two]) (set (prime-factors (* prime-one prime-two)))))))
  32. (deftest test-factors-of-nine (testing "returns [3 3] for 9" (is (=

    [3 3] (prime-factors 9))))) (defspec check-prime-times-prime-has-two-prime-factors 1000 (testing "Factoring prime * prime returns both primes" (prop/for-all [prime-one (gen/elements primes) prime-two (gen/elements primes)] (= (set [prime-one prime-two]) (set (prime-factors (* prime-one prime-two)))))))
  33. (deftest test-factors-of-nine (testing "returns [3 3] for 9" (is (=

    [3 3] (prime-factors 9))))) (defspec check-prime-times-prime-has-two-prime-factors 1000 (testing "Factoring prime * prime returns both primes" (prop/for-all [prime-one (gen/elements primes) prime-two (gen/elements primes)] (= (set [prime-one prime-two]) (set (prime-factors (* prime-one prime-two)))))))
  34. (defspec check-product-of-primes-returns-all-primes 1000 (testing "Factoring the product of a series

    of primes returns all the primes" (prop/for-all [prime-seq (gen/vector (gen/elements primes))] (= (sort prime-seq) (prime-factors (apply *' prime-seq))))))
  35. (defspec check-product-of-primes-returns-all-primes 1000 (testing "Factoring the product of a series

    of primes returns all the primes" (prop/for-all [prime-seq (gen/vector (gen/elements primes))] (= (sort prime-seq) (prime-factors (apply *' prime-seq))))))
  36. (deftest test-factors-of-some-big-number (testing "returns [2 2 2 3 3 5

    13 23 131] for 14100840" (is (= [2 2 2 3 3 5 13 23 131] (prime-factors (* 2 2 3 3 5 13 23 131)))))
  37. $ lein test lein test :only prime-factors.core-test/test-factors-of-some-big-number FAIL in (test-factors-of-some-big-number)

    (core_test.clj:32) returns [2 2 2 3 3 5 13 23 131] for 14100840 expected: (= [2 2 2 3 3 5 13 23 131] (prime-factors (* 2 2 3 3 5 13 23 131))) actual: (not (= [2 2 2 3 3 5 13 23 131] [2 2 3 3 5 13 23 131])) Ran 13 tests containing 13 assertions. 1 failures, 0 errors. Tests failed.
  38. $ lein test lein test :only prime-factors.core-test/test-factors-of-some-big-number FAIL in (test-factors-of-some-big-number)

    (core_test.clj:32) returns [2 2 2 3 3 5 13 23 131] for 14100840 expected: (= [2 2 2 3 3 5 13 23 131] (prime-factors (* 2 2 3 3 5 13 23 131))) actual: (not (= [2 2 2 3 3 5 13 23 131] [2 2 3 3 5 13 23 131])) Ran 13 tests containing 13 assertions. 1 failures, 0 errors. Tests failed.
  39. (defspec check-product-of-primes-returns-all-primes 1000 (testing "Factoring the product of a series

    of primes returns all the primes" (prop/for-all [prime-seq (gen/vector (gen/elements primes))] (= prime-seq (prime-factors (apply *' prime-seq))))))
  40. $ lein test lein test prime-factors.core-check {:result false, :seed 1469999806348,

    :failing-size 5, :num-tests 6, :fail [[4483 2251 7309 971 6199]], :shrunk {:total-nodes-visited 87, :depth 17, :result false, :smallest [[3 2]]}, :test-var "check-product-of-primes-returns-all-primes"} FAIL in (check-product-of-a-series-of-primes-returns-all-primes) (clojure_test.cljc:21) expected: result actual: false {:result true, :num-tests 1000, :seed 1469999806440, :test-var "check-two-times-prime-has-two-prime-factors"} {:result true, :num-tests 1000, :seed 1469999807020, :test-var "check-primes-have-one-prime-factor"} {:result true, :num-tests 1000, :seed 1469999807577, :test-var "check-prime-times-prime-has-two-prime-factors"} Tests failed.
  41. $ lein test lein test prime-factors.core-check {:result false, :seed 1469999806348,

    :failing-size 5, :num-tests 6, :fail [[4483 2251 7309 971 6199]], :shrunk {:total-nodes-visited 87, :depth 17, :result false, :smallest [[3 2]]}, :test-var "check-product-of-primes-returns-all-primes"} FAIL in (check-product-of-a-series-of-primes-returns-all-primes) (clojure_test.cljc:21) expected: result actual: false {:result true, :num-tests 1000, :seed 1469999806440, :test-var "check-two-times-prime-has-two-prime-factors"} {:result true, :num-tests 1000, :seed 1469999807020, :test-var "check-primes-have-one-prime-factor"} {:result true, :num-tests 1000, :seed 1469999807577, :test-var "check-prime-times-prime-has-two-prime-factors"} Tests failed.
  42. $ lein test lein test prime-factors.core-check {:result false, :seed 1469999806348,

    :failing-size 5, :num-tests 6, :fail [[4483 2251 7309 971 6199]], :shrunk {:total-nodes-visited 87, :depth 17, :result false, :smallest [[3 2]]}, :test-var "check-product-of-primes-returns-all-primes"} FAIL in (check-product-of-a-series-of-primes-returns-all-primes) (clojure_test.cljc:21) expected: result actual: false {:result true, :num-tests 1000, :seed 1469999806440, :test-var "check-two-times-prime-has-two-prime-factors"} {:result true, :num-tests 1000, :seed 1469999807020, :test-var "check-primes-have-one-prime-factor"} {:result true, :num-tests 1000, :seed 1469999807577, :test-var "check-prime-times-prime-has-two-prime-factors"} Tests failed.
  43. $ lein test lein test prime-factors.core-check {:result false, :seed 1469999806348,

    :failing-size 5, :num-tests 6, :fail [[4483 2251 7309 971 6199]], :shrunk {:total-nodes-visited 87, :depth 17, :result false, :smallest [[3 2]]}, :test-var "check-product-of-primes-returns-all-primes"} FAIL in (check-product-of-a-series-of-primes-returns-all-primes) (clojure_test.cljc:21) expected: result actual: false {:result true, :num-tests 1000, :seed 1469999806440, :test-var "check-two-times-prime-has-two-prime-factors"} {:result true, :num-tests 1000, :seed 1469999807020, :test-var "check-primes-have-one-prime-factor"} {:result true, :num-tests 1000, :seed 1469999807577, :test-var "check-prime-times-prime-has-two-prime-factors"} Tests failed.
  44. $ lein test lein test prime-factors.core-check {:result false, :seed 1469999806348,

    :failing-size 5, :num-tests 6, :fail [[4483 2251 7309 971 6199]], :shrunk {:total-nodes-visited 87, :depth 17, :result false, :smallest [[3 2]]}, :test-var "check-product-of-primes-returns-all-primes"} FAIL in (check-product-of-a-series-of-primes-returns-all-primes) (clojure_test.cljc:21) expected: result actual: false {:result true, :num-tests 1000, :seed 1469999806440, :test-var "check-two-times-prime-has-two-prime-factors"} {:result true, :num-tests 1000, :seed 1469999807020, :test-var "check-primes-have-one-prime-factor"} {:result true, :num-tests 1000, :seed 1469999807577, :test-var "check-prime-times-prime-has-two-prime-factors"} Tests failed.