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.8k
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
ヘブンバーンズレッドにおける、世界観を活かしたミニゲーム企画の作り方
gree_tech
PRO
0
430
Function Body Macros で、SwiftUI の View に Accessibility Identifier を自動付与する/Function Body Macros: Autogenerate accessibility identifiers for SwiftUI Views
miichan
2
150
Skrub: machine-learning with dataframes
gaelvaroquaux
0
110
実践AIガバナンス
asei
3
290
250905 大吉祥寺.pm 2025 前夜祭 「プログラミングに出会って20年、『今』が1番楽しい」
msykd
PRO
1
210
なぜSaaSがMCPサーバーをサービス提供するのか?
sansantech
PRO
5
1.4k
制約理論(ToC)入門
recruitengineers
PRO
9
3.7k
Bye-Bye Query Spaghetti: Write Queries You'll Actually Understand Using Pipelined SQL Syntax
tobiaslampertlotum
0
120
AI時代に非連続な成長を実現するエンジニアリング戦略
sansantech
PRO
3
920
トヨタ生産方式(TPS)入門
recruitengineers
PRO
6
1.4k
ソフトウェア エンジニアとしての 姿勢と心構え
recruitengineers
PRO
26
12k
まだ間に合う! StrandsとBedrock AgentCoreでAIエージェント構築に入門しよう
minorun365
PRO
11
720
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
Thoughts on Productivity
jonyablonski
69
4.8k
Docker and Python
trallard
45
3.5k
The Language of Interfaces
destraynor
160
25k
Speed Design
sergeychernyshev
32
1.1k
Designing Experiences People Love
moore
142
24k
We Have a Design System, Now What?
morganepeng
53
7.8k
What's in a price? How to price your products and services
michaelherold
246
12k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Being A Developer After 40
akosma
90
590k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
510
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