Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Property Based Testing
Search
Mathias Verraes
April 06, 2016
Technology
1
2.7k
Property Based Testing
5min lightning talk for the SoCraTes Belgium meetup and CukeUp London.
Mathias Verraes
April 06, 2016
Tweet
Share
More Decks by Mathias Verraes
See All by Mathias Verraes
On Being Explicit
mathiasverraes
0
3k
How to Find the Bar
mathiasverraes
1
2.1k
Designed Stickiness
mathiasverraes
1
2.2k
The Monty Hall Problem with Haskell
mathiasverraes
0
2.8k
The World's Shortest and Most Chaotic Introduction to Event Storming
mathiasverraes
2
2.7k
Towards Modelling Processes
mathiasverraes
3
5.8k
Modelling Heuristics
mathiasverraes
1
3k
Object Reorientation
mathiasverraes
6
2.9k
Small Controlled Experiments
mathiasverraes
1
4.2k
Other Decks in Technology
See All in Technology
Eight Engineering Unit 紹介資料
sansan33
PRO
0
5.7k
Microsoft Agent 365 を 30 分でなんとなく理解する
skmkzyk
1
190
Master Dataグループ紹介資料
sansan33
PRO
1
4k
MCP・A2A概要 〜Google Cloudで構築するなら〜
shukob
0
150
AI 時代のデータ戦略
na0
8
3.2k
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
37k
Ryzen NPUにおけるAI Engineプログラミング
anjn
0
190
“決まらない”NSM設計への処方箋 〜ビットキーにおける現実的な指標デザイン事例〜 / A Prescription for "Stuck" NSM Design: Bitkey’s Practical Case Study
bitkey
PRO
1
310
オープンデータの内製化から分かったGISデータを巡る行政の課題
naokim84
2
1.3k
ページの可視領域を算出する方法について整理する
yamatai1212
0
160
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
0
640
Agents IA : la nouvelle frontière des LLMs (Tech.Rocks Summit 2025)
glaforge
0
360
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Mobile First: as difficult as doing things right
swwweet
225
10k
GraphQLとの向き合い方2022年版
quramy
49
14k
Rails Girls Zürich Keynote
gr2m
95
14k
Fireside Chat
paigeccino
41
3.7k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.6k
The World Runs on Bad Software
bkeepers
PRO
72
12k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
960
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
Transcript
Property Based Testing @mathiasverraes
None
function inc(x) { return x + 1; }
inc x = x + 1
-- Tests double 1 `should_be` 2 double 2 `should_be` 4
-- Implementation double x | x == 1 = 2 | x == 2 = 4
A property of double double_is_always_even :: Int -> Bool double_is_always_even
x = even (double x)
> quickCheck double_is_always_even Failed: 0 (after 1 test) Exception: Non-exhaustive
patterns in function double
double x = x * 2
quickCheck double_is_always_even Passed: 0 Passed: 1 Passed: -3 Passed: -1
(...) Passed: -58 Passed: 89 +++ OK, passed 100 tests.
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
Distributivity Law reverse_is_distributive xs ys = reverse (xs++ys) == reverse
xs ++ reverse ys
> 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]
Oops... reverse_is_distributive xs ys = reverse (xs++ys) == reverse ys
++ reverse xs
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.
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
-- 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
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]
-- property unsplit_inverses_split str = forAll (elements str) (\char ->
unsplit char (split char str) == str)
> 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'
split 'a' "a" == [""] unsplit 'a' [""] == ""
-- should be: split 'a' "a" == ["", ""] unsplit 'a' ["", ""] == "a"
Modify the definition of split split char [] = []
... -- becomes split char [] = [""] ... > quickCheck unsplit_inverses_split +++ OK, passed 100 tests.
Property Based Testing → test lots of random cases cheaply
→ encourage thinking about general properties Thanks :-) @mathiasverraes