Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Check Your Work: An Introduction to Property-Ba...
Search
Connor Mendenhall
August 04, 2016
41
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Check Your Work: An Introduction to Property-Based Testing
Connor Mendenhall
August 04, 2016
More Decks by Connor Mendenhall
See All by Connor Mendenhall
Monitor What Matters
ecmendenhall
0
45
Serverless Integration Patterns
ecmendenhall
0
250
Intro to Git
ecmendenhall
0
89
Economics of Web Security
ecmendenhall
0
51
PGP for Developers
ecmendenhall
0
140
Mac_security_basics.pdf
ecmendenhall
0
58
Featured
See All Featured
Chasing Engaging Ingredients in Design
codingconduct
0
340
Discover your Explorer Soul
emna__ayadi
2
1.3k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
330
Build your cross-platform service in a week with App Engine
jlugia
234
19k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
710
Leo the Paperboy
mayatellez
10
2.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Designing Powerful Visuals for Engaging Learning
tmiket
1
580
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
700
Transcript
Check Your Work An introduction to property-based testing Connor Mendenhall
@ecmendenhall 8th Light
None
Can we do better?
None
Have you performed the right tests? —“Out of the Tar
Pit”
None
None
None
Values “add(1,2) equals 3” “sort([1,5,3,4]) returns [1,3,4,5]” “MyCoolModel.save() is the
same as MyCoolModel.save().save()”
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.”
Prime factors
Prime factors 4 = 2·2 17 = 17 30 =
2·3·5 31878 = 2·3·3·7·11·23
Prime factors 4 = 2·2 17 = 17 30 =
2·3·5 31878 = 2·3·3·7·11·23
Prime factors 4 = 2·2 17 = 17 30 =
2·3·5 31878 = 2·3·3·7·11·23
Prime factors 4 = 2·2 17 = 17 30 =
2·3·5 31878 = 2·3·3·7·11·23
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]
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(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 []))
(deftest test-factors-of-one (testing "returns [] for 1" (is (= []
(prime-factors 1)))))
(deftest test-factors-of-two (testing "returns [2] for 2" (is (= [2]
(prime-factors 2)))))
(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)))))
(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)))))
(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)))))
(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)))))
(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)))))
(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)))))
(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)))))
(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))))))
(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))))))
(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))))))
(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)))))))
(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)))))))
(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)))))))
(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)))))))
(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))))))
(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))))))
(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)))))
$ 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.
$ 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.
(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))))))
$ 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.
$ 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.
$ 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.
$ 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.
$ 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.
Can we do better?
Show Your Work
Check Your Work Show Your Work