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 is a Mindset
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Andrea Leopardi
December 06, 2017
Programming
720
0
Share
Property-based Testing is a Mindset
Andrea Leopardi
December 06, 2017
More Decks by Andrea Leopardi
See All by Andrea Leopardi
The Umbrella and the Range
whatyouhide
0
45
gen_statem - OTP's Unsung Hero
whatyouhide
2
320
The World is a Network (and We Are Just Nodes)
whatyouhide
1
250
BEAM: The Perfect Fit for Networks
whatyouhide
1
250
Update from the Elixir team - 2022
whatyouhide
0
450
Testing Asynchronous OTP
whatyouhide
1
560
Elixir Sightseeing Tour
whatyouhide
0
470
Mint - Disrupting HTTP clients
whatyouhide
0
290
BEAM Architecture Handbook
whatyouhide
7
2.9k
Other Decks in Programming
See All in Programming
今からFlash開発できるわけないじゃん、ムリムリ! (※ムリじゃなかった!?)
arkw
0
170
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
280
20260320登壇資料
pharct
0
140
AI時代のシステム設計:ドメインモデルで変更しやすさを守る設計戦略
masuda220
PRO
6
1.1k
Codex CLI でつくる、Issue から merge までの開発フロー
amata1219
0
270
Redox OS でのネームスペース管理と chroot の実現
isanethen
0
500
一度始めたらやめられない開発効率向上術 / Findy あなたのdotfilesを教えて!
k0kubun
3
2.7k
安いハードウェアでVulkan
fadis
1
870
AI 開発合宿を通して得た学び
niftycorp
PRO
0
190
Tamach-sre-3_ANDPAD-shimaison93
mane12yurks38
0
230
Xdebug と IDE による デバッグ実行の仕組みを見る / Exploring-How-Debugging-Works-with-Xdebug-and-an-IDE
shin1x1
0
300
Smarter Angular mit Transformers.js & Prompt API
christianliebel
PRO
1
110
Featured
See All Featured
Music & Morning Musume
bryan
47
7.1k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
470
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
110
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
150
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
420
What's in a price? How to price your products and services
michaelherold
247
13k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
140
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.1k
Transcript
I S A M I N D S E T
P R O P E R T Y - B A S E D T E S T I N G
@whatyouhide
None
Elixir
T E S T I N G
why do we test? no tests yes tests
unit tests
test "sorting" do assert sort([]) == [] assert sort([1, 2,
3]) == [1, 2, 3] assert sort([2, 1, 3]) == [1, 2, 3] end example-based
table-based Input Output [] [] [1, 2, 3] [1, 2,
3] [2, 1, 3] [1, 2, 3]
unit tests , but also
P R O P E R T I E S
hard to write , but...
valid inputs properties of output testing framework
github.com/whatyouhide/stream_data
example time: sorting lists
test "sorting" do assert sort([]) == [] assert sort([1, 2,
3]) == [1, 2, 3] assert sort([2, 1, 3]) == [1, 2, 3] end
lists of integers
it's a list has the same elements it's ordered
check all list <- list_of(int()) do sorted = sort(list) assert
is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
check all list <- list_of(int()) do sorted = sort(list) assert
is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
check all list <- list_of(int()) do sorted = sort(list) assert
is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
check all list <- list_of(int()) do sorted = sort(list) assert
is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
check all list <- list_of(int()) do sorted = sort(list) assert
is_list(sorted) assert same_elements?(list, sorted) assert ordered?(sorted) end
def sort(list), do: list
[32, 2, 44, -12] [1, 0] *shrinking
P A T T E R N S
circular code
decode(encode(term)) == term
property "encoding->decoding is circular" do check all bin <- binary()
do encoded = Huffman.encode(bin) assert is_binary(encoded) assert Huffman.decode(encoded) == bin end end Huffman encoding
oracle model
my_code() == oracle_code()
older system less performant implementation
property "gives same results as Erlang impl" do check all
bin <- binary() do assert Huffman.encode(bin) == :huffman.encode(bin) end end
smoke tests https://www.youtube.com/watch?v=jvwfDdgg93E
API: 200, 201, 400, 404 https://www.youtube.com/watch?v=jvwfDdgg93E
https://www.youtube.com/watch?v=jvwfDdgg93E property "only expected codes are returned" do check all
request <- request() do response = HTTP.perform(request) assert response.status in [200, 201, 400, 404] end end
locally , CI
if System.get_env("CI") == "true" do config :stream_data, max_runs: 500 else
config :stream_data, max_runs: 25 end
unit + properties
R E A L - W O R L D
E X A M P L E
Redis parser
continuation parser parse(bytes) {:ok, command} {:more, function}
property "splitting commands at random" do check all cmd <-
command(), split_cmd <- random_splits(cmd) do assert {:ok, _, ""} = parse_many(split_cmd) end end
property "splitting commands at random" do check all cmd <-
command(), split_cmd <- random_splits(cmd) do assert {:ok, _, ""} = parse_many(split_cmd) end end
property "splitting commands at random" do check all cmd <-
command(), split_cmd <- random_splits(cmd) do assert {:ok, _, ""} = parse_many(split_cmd) end end
S T A T E F U L T E
S T I N G
model valid commands +
model: state + state transformations
commands: calls + preconditions
bounded-size queue
Max size model system
•push(queue, value) •resize(queue, max_size) commands
def push(model, _value), do: model def resize(_model, max_size), do: max_size
push(queue, {:some, "value"}) push(queue, [123, 3.2]) resize(queue, 1) push(queue, %{})
assert size(queue) <= model
LevelDB
17 (seventeen) calls 33 (thirty three) calls
C O N C L U S I O N
find obscure bugs reduce to minimal failing input find specification
errors keep increasing input space
v1.7
use stream_data
use property-based testing
@whatyouhide github.com/whatyouhide/stream_data