Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
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.7k
The World's Shortest and Most Chaotic Introduction to Event Storming
mathiasverraes
2
2.7k
Towards Modelling Processes
mathiasverraes
3
5.7k
Modelling Heuristics
mathiasverraes
1
2.9k
Object Reorientation
mathiasverraes
6
2.8k
Small Controlled Experiments
mathiasverraes
1
4.1k
Other Decks in Technology
See All in Technology
AIとSREの未来 / AI and SRE
ymotongpoo
2
1.1k
RDRA3.0を知ろう
kanzaki
2
430
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
8
65k
Devin&Cursor、それぞれの「本質」から導く最適ユースケース戦略
empitsu
8
2.4k
What's Next in OpenShift Q2 CY2025
redhatlivestreaming
1
800
ゴリラ.vim #36 ~ Vim x SNS ~ スポンサーセッション
yasunori0418
1
350
MCP Clientを活用するための設計と実装上の工夫
yudai00
1
800
令和最新版TypeScriptでのnpmパッケージ開発
lycorptech_jp
PRO
0
110
Azure Developer CLI と Azure Deployment Environment / Azure Developer CLI and Azure Deployment Environment
nnstt1
1
120
2025advance01
minamizaki
0
130
Machine Intelligence for Vision, Language, and Actions
keio_smilab
PRO
0
490
ローカル環境でAIを動かそう!
falken
PRO
1
170
Featured
See All Featured
A Tale of Four Properties
chriscoyier
159
23k
BBQ
matthewcrist
88
9.7k
KATA
mclloyd
29
14k
Designing for humans not robots
tammielis
253
25k
Optimizing for Happiness
mojombo
378
70k
The Language of Interfaces
destraynor
158
25k
Adopting Sorbet at Scale
ufuk
76
9.4k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
32
5.8k
It's Worth the Effort
3n
184
28k
Building Applications with DynamoDB
mza
95
6.4k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
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