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
Andrea Leopardi
December 06, 2017
Programming
0
690
Property-based Testing is a Mindset
Andrea Leopardi
December 06, 2017
Tweet
Share
More Decks by Andrea Leopardi
See All by Andrea Leopardi
gen_statem - OTP's Unsung Hero
whatyouhide
1
180
The World is a Network (and We Are Just Nodes)
whatyouhide
1
200
BEAM: The Perfect Fit for Networks
whatyouhide
1
180
Update from the Elixir team - 2022
whatyouhide
0
390
Testing Asynchronous OTP
whatyouhide
1
510
Elixir Sightseeing Tour
whatyouhide
0
410
Mint - Disrupting HTTP clients
whatyouhide
0
240
BEAM Architecture Handbook
whatyouhide
7
2.8k
The Evolution of a Language
whatyouhide
0
140
Other Decks in Programming
See All in Programming
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
14
4.1k
Agentic Applications with Symfony
el_stoffel
1
170
AI Coding Agent Enablement - エージェントを自走させよう
yukukotani
12
4k
Kamal 2 – Get Out of the Cloud
aleksandrov
0
140
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
1.1k
PHPのガベージコレクションを深掘りしよう
rinchoku
0
260
小さく段階的リリースすることで深夜メンテを回避する
mkmk884
2
150
SLI/SLOの設定を進めるその前に アラート品質の改善に取り組んだ話
tanden
2
770
Day0 初心者向けワークショップ実践!ソフトウェアテストの第一歩
satohiroyuki
0
510
Modern Angular:Renovation for Your Applications @angularDays 2025 Munich
manfredsteyer
PRO
0
160
Devinのメモリ活用の学びを自社サービスにどう組み込むか?
itarutomy
0
1.9k
Productivity is Messing Around and Having Fun
hollycummins
0
170
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
25k
Visualization
eitanlees
146
16k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
177
52k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.6k
Code Reviewing Like a Champion
maltzj
522
39k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
4 Signs Your Business is Dying
shpigford
183
22k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
12
630
Designing Experiences People Love
moore
141
23k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
17
1.1k
How GitHub (no longer) Works
holman
314
140k
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