SlideShare a Scribd company logo
1 of 48
Download to read offline
Andrzej Jóźwiak
andrzej.jozwiak@gmail.com
https://github.com/artificialrevelations
Property
Based Tests
And Where
To Find Them
meetup.juglodz.pl
yt.juglodz.pl
fb.juglodz.pl
2
Exploits of a Mom: https://xkcd.com/327/ 3
Poll: Unit tests ...
A. are exhaustive
B. guarantee the correctness
C. help find unknown cases
D. all of the above
E. it really depends on the context
4
Would you like to play a game?
Can your unit tests ...
5
find out that the car brakes do not work
when volume on the radio is changed?
Can your unit tests ...
Experiences with QuickCheck: https://www.cs.tufts.edu/~nr/cs257/archive/john-hughes/quviq-testing.pdf 6
Bypassing Android lockscreen: https://sites.utexas.edu/iso/2015/09/15/android-5-lockscreen-bypass/
find out that putting enough text in the
Android lock screen text field can crash it
and give full access to the phone?
Can your unit tests ...
7
A Formal Specification of a File Synchronizer: https://www.cis.upenn.edu/~bcpierce/papers/unisonspec.pdf
find out that your secure file storage is
not secure and is losing data?
Can your unit tests ...
8
find out that going back and forth through
a list of available voices can cause the
app to play an incorrect voice?
Can your unit tests ...
my own child sure can!
9
This is a thing that we found out in our own app
10
Twitter: https://twitter.com/cbirchall/status/1209156343904587779
All unit tests passing do not always guarantee correctness...
11
And now for an academic example...
public static <A> List<A> reverse(final List<A> original) {
final int size = original.size();
final List<A> reversed = new ArrayList<>(size);
// going from the last element to the first of the
original list
for (int i = size - 1; i >= 0; i--) {
// thus adding the elements in the reversed order
reversed.add(original.get(i));
}
return reversed;
}
What are the properties of the code here?
Github: https://git.io/JfDGP
12
Lists reverse function example based tests
Github: https://git.io/JfDGa
13
Let’s build an example property...
Github: https://git.io/JfDZS
@Test
public void reverse_reversed_equals_original() {
// given:
final List<String> tested = Arrays.asList("This", "is", "a", "test");
// when:
final List<String> result = reverse(reverse(tested));
// then:
assertEquals(tested, result);
// Should we create more examples?
}
14
Let’s build a property based testing framework ...
We will notice soon enough that something is missing
15
Let’s build a property based testing framework ...
private interface Property<A> {
boolean check(A value);
}
private static <A> Property<List<A>> reverseOfReversedEqualsOriginal ()
{
return original -> reverse(reverse(original)).equals(original);
}
Github: https://git.io/JfDZS
16
Let’s build a property based testing framework ...
private interface Generator<A> {
A generate(Random seed);
}
// A very simple generator that produces lists:
// - with size varying from 0 to 100
// - with elements being numbers from 0 to 100 as strings
private Generator<List<String>> randomStringListsGenerator () {
return seed -> {
final int randomSize = randInt(seed, 0, 100);
final List<String> randomizedList = new
ArrayList<>(randomSize);
for (int i = 0; i < randomSize; i++) {
randomizedList .add(String.valueOf(randInt(seed, 0, 100)));
}
return randomizedList ;
};
}
Github: https://git.io/JfDZS
17
Let’s build a property based testing framework ...
private static <A> void quickCheck(final long seedValue,
final int numberOfTries,
final Property<A> property,
final Generator<A> generator) {
final Random seed = new Random(seedValue);
for (int i = 0; i < numberOfTries; i++) {
final A tested = generator.generate(seed);
final boolean result = property.check(tested);
if (!result) {
final StringBuilder builder =
new StringBuilder()
.append("Property test failed")
.append("nSeed value: ")
.append(seedValue)
.append("nExample data: ")
.append(tested);
throw new AssertionError(builder);
}
}
}
Github: https://git.io/JfDZS
18
Let’s build a property based testing framework ...
@Test
public void custom_reverse_property_test() {
final int numberOfTries = 1000;
final long seedValue = new Random().nextLong();
final Property<List<String>> reverseProperty =
reverseOfReversedEqualsOriginal();
final Generator<List<String>> generator =
randomStringListsGenerator();
quickCheck(seedValue, numberOfTries, reverseProperty, generator);
}
Github: https://git.io/JfDZS
19
We are lucky! The example only has 19 elements, what
would happen if it had 1000 or 10000 elements?
private static <A> Property<List<A>> reverseWrongProperty() {
return original -> reverse(original).equals(original);
}
Github: https://git.io/JfDZS
java.lang.AssertionError: Property test failed
Seed value: -2569510089704470893
Example data: [40, 15, 20, 30, 36, 35, 55, 99, 89, 93, 67, 27,
31, 95, 26, 6, 84, 23, 92]
How can we know our little framework is correct?
20
What about a professional solution?
Github: https://git.io/JfDZS
@Property
@Report(Reporting.GENERATED)
public boolean broken_reverse_property
(@ForAll List<?> original) {
return Lists.reverse(original).equals(original);
}
|-------------------jqwik-------------------
tries = 1 | # of calls to property
checks = 1 | # of not rejected calls
generation-mode = RANDOMIZED | parameters are randomly generated
after-failure = PREVIOUS_SEED | use the previous seed
seed = -1616208483702989146 | random seed to reproduce generated values
sample = [[Any[0], Any[1]]]
original-sample = [[Any[64], Any[226], Any[319], Any[71], Any[351], Any[137],
Any[9], Any[262], Any[239], Any[485], Any[23], Any[265], Any[108], Any[348],
Any[202], Any[365], Any[147], Any[347], Any[133]]]
It also found a 19 element example but managed to shrink it to 2
21
Poll: Our framework was missing ...
A. a way to shrink the example to smallest possible
size
B. a way to shrink the values used by the example
C. pretty printing of the output
D. all of the above
E. nothing, It was perfect!
F. I bet there is something more!
22
Our framework was missing ...
Are there well established categories of
properties?
23
Before we leave the realm of academic examples...
and the Math behind them is minimal! I promise.
24
Property Category: Encode/Decode
25
Property Category: Encode/Decode
Twitter: https://github.com/btlines/pbdirect
26
Property Category: Encode/Decode
Twitter: https://github.com/btlines/pbdirect
27
Property Category: Invariants
28
Property Category: Invariants
size of the collection: some operations on collections do not change their size but
only modify the order of elements or their state like sorting, mapping
content of the collection: some operations on collections do not change their
content (do not remove or add elements), it’s possible to find all elements but just in a
different order
order of elements: some operations change the characteristics of elements but do
not change their order
domain specific: premium users will always have a special discount regardless of the
amount of items on their shopping cart. We can always find properties of our model
that do not changed regardless of operations applied.
29
Property Category: Idempotence
30
Property Category: Idempotence
absolute value of an integer: abs(abs(x)) = abs(x)
floor, ceiling functions: ceil(ceil(x)) = ceil(x)
database search: searching for an element in a database multiple times should give
us the same results each time. This only holds in a case where there are no updates in
between.
sorting: sorting a collection multiple times should give us the same result, sorting an
already sorted collection should give us the same result, the same applies for filtering,
searching for distinct elements etc.
crosswalk button: pressing a crosswalk button multiple times will not change the end
result of the lights changing from red to green.
31
Property Category: Different paths lead to the same destination
32
Property Category: Different paths lead to the same destination
commutative property of addition: x + y = y + x, for all x, y ∈ R
putting socks on your feet: does it matter in which order we will put our socks on? If
the thing that we would like end up with are both feet in socks, then it does not matter
if we start with left or right foot!
applying discount code to the shopping cart: does it matter if we apply the discount
code to an empty cart (ofc if the API allows to start shopping like this) before we add
the items? The result should be the same for when we apply the discount to already
filled shopping cart.
putting ingredients on your pizza: does it matter if we start with pineapple or ham if
we want to have great pizza? I know I know this example is controversial!
filtering and sorting the results: the end result should be the same if we start from
sorting and then filter out the unwanted results. Let’s not focus on the issue of
optimization
33
Property Category: Test Oracle
34
Property Category: Test Oracle
result should stay the same: code after refactoring should give the same results as
the original one for the same input. This can be applied for any kind of code not only
examples like sorting or filtering. If we are reworking some UI elements to support
new cases it should behave the same like the old one for all old cases.
the new algorithm should not have worse performance then the old one: if the
refactored code should use less memory, use less hard drive space, perform less
operations, in other words just be better in some way or at least not worse, then
comparing old with new is the way to go.
when writing a property is not obvious: instead of finding a property of the code like
encode/decode or different paths same result, we can base our tests on the already
existing code and its results.
OK. Everything is nice but I am not writing
sorting for my day job!
35
Now off to the real world...
or reverse, or map, or json encoding for that matter
36
1. open new database
2. put key1 and val1
3. close database
4. open database
5. delete key2
6. delete key1
7. close database
8. open database
9. delete key2
10. close database
11. open database
12. put key3 and val1
13. close database
14. open database
15. close database
16. open database
17. seek first
Expected output? key3
Actual output? key1
Reappearing "ghost" key after 17 steps: https://github.com/google/leveldb/issues/50
A ghost story ...
Would you come up with such an example?
37
Reappearing "ghost" key after 17 steps: https://github.com/google/leveldb/issues/50
A ghost story - a rehaunting ...
After a patch that was supposedly fixing the issue a new example was found
this time made up from 33 steps. After almost a month it was finally fixed.
Fixed bug in picking inputs for a level-0 compaction.
When finding overlapping files, the covered range may expand as files are added
to the input set. We now correctly expand the range when this happens instead
of continuing to use the old range. This change fixes a bug related to deleted
keys showing up incorrectly after a compaction.
38
Stateful testing...
39
Stateful testing...
Model - describes the current expected state of the system. Often we know what to
expect from the code, it does not matter how the code gets to that result.
Commands - represent what the system under test should do, command generation
needs to take into account the current model state.
Validation - way to check the current model state and compare it with the system
under test state.
SUT - system under test, stateful in it’s nature
40
A stateful representation of a shopping cart ...
public class ShoppingCart {
public Quantity get(Product product)
public List<Product> getAllProducts ()
public Quantity add(Product product, Quantity quantity)
public Quantity remove(Product product, Quantity quantity)
public void clear()
public void setDiscount(DiscountCode code)
public void clearDiscount()
public Price getTotalPrice()
public Quantity getTotalQuantity ()
}
41
A simplified shopping cart model ...
public class ShoppingCartModel {
private List<ShoppingCartModelElement> products = new
LinkedList<>();
private int discount = 0; //%
private static class ShoppingCartModelElement {
public String product;
public int price;
public int quantity;
}
}
42
A simplified representation of a command in our system ...
public interface Command<M, S> {
boolean preconditions(final M model);
void execute(final M model, final S sut);
void postconditions (final M model, final S sut);
}
43
An implementation of one of the available commands ...
public class AddProductCommand implements Command<ShoppingCartModel , ShoppingCart >
{
public void execute(final ShoppingCartModel model,
final ShoppingCart sut) {
model.addProduct(
product .getName(),
quantity .getValue(),
product .getPrice().getValue()
);
sut.add( product, quantity);
}
public void postconditions (final ShoppingCartModel model,
final ShoppingCart sut) {
Assertions.assertEquals(
model.getQuantity( product.getName()),
sut.get( product).getValue()
);
}
44
Available commands for our property test
- AddProductCommand
- RemoveProductCommand
- GetProductCommand
- GetAllProductsCommand
- ClearProductCommand
- ClearCommand
- ClearProductCommand
- SetDiscountCommand
- ClearDiscountCommand
- GetTotalPriceCommand
- GetTotalQuantityCommand
Now we need to create random sequences of commands that will stress the
implementation of our stateful component.
45
Testing properties of a shopping cart ...
Let’s introduce a bug in the shopping cart:
- if the shopping carts has 3 or more elements
- it will NOT add any more elements
Run failed after following actions:
AddProductCommand{ product=Product{name='AAA', price=Price(3)},
quantity=Quantity(1)}
AddProductCommand{ product=Product{name='AAa', price=Price(3)},
quantity=Quantity(1)}
AddProductCommand{ product=Product{name='ABA', price=Price(3)},
quantity=Quantity(1)}
AddProductCommand{ product=Product{name='AAB', price=Price(3)},
quantity=Quantity(1)}
46
Testing properties of a shopping cart ...
original-sample = [ActionSequence[FAILED]: [SetDiscountCommand{discount=Discount(58)},
GetTotalQuantityCommand{}, ClearCommand{}, SetDiscountCommand{discount=Discount(100)},
SetDiscountCommand{discount=Discount(58)}, GetTotalQuantityCommand{},
GetTotalPriceCommand{}, ClearDiscountCommand{}, SetDiscountCommand{discount=Discount(18)},
GetTotalQuantityCommand{}, GetTotalPriceCommand{}, ClearCommand{},
GetTotalQuantityCommand{}, AddProductCommand{ product=Product{name='ZzZaWB',
price=Price(6)}, quantity=Quantity(60)}, GetTotalPriceCommand{}, AddProductCommand{
product=Product{name='zEfaZZga', price=Price(8)}, quantity=Quantity(74)},
GetTotalPriceCommand{}, ClearDiscountCommand{}, AddProductCommand{
product=Product{name='faGZQAGAQ', price=Price(9)}, quantity=Quantity(154)},
GetTotalQuantityCommand{}, AddProductCommand{ product=Product{name='ZVdJaj',
price=Price(6)}, quantity=Quantity(66)}, SetDiscountCommand{discount=Discount(32)},
GetTotalQuantityCommand{}, GetTotalQuantityCommand{}, GetTotalQuantityCommand{},
AddProductCommand{ product=Product{name='AAzZza', price=Price(6)},
quantity=Quantity(5)}]]
47
Thesis Defense: https://xkcd.com/1403/
Q&A time ...
48
Further reading:
(book) PropEr Testing https://propertesting.com/toc.html
(documentation) QuickCheck: https://hackage.haskell.org/package/QuickCheck
(article) Introduction to PBT: https://fsharpforfunandprofit.com/posts/property-based-testing/
(documentation) jqwik: https://jqwik.net/
(presentation) Stateful PBT: https://www.youtube.com/watch?v=owHmYA52SIM
(presentation) Don’t Write Tests: https://www.youtube.com/watch?v=hXnS_Xjwk2Y
(presentation) Testing the Hard Stuff: https://www.youtube.com/watch?v=zi0rHwfiX1Q
(examples): https://github.com/artificialrevelations/property-based-testing-workshop

More Related Content

What's hot

Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner codeMite Mitreski
 
Elixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangElixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangLaura M. Castro
 
Functional programming's relentless bug hunter claire
Functional programming's relentless bug hunter  claireFunctional programming's relentless bug hunter  claire
Functional programming's relentless bug hunter claireadamcbaker
 
An Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersAn Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersFITC
 
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...Haris Mahmood
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016Codemotion
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingCodemotion
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Danny Preussler
 
Android testing
Android testingAndroid testing
Android testingSean Tsai
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action scriptChristophe Herreman
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptMichael Girouard
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingRichardWarburton
 
Thirteen ways of looking at a turtle
Thirteen ways of looking at a turtleThirteen ways of looking at a turtle
Thirteen ways of looking at a turtleScott Wlaschin
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 

What's hot (20)

Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
ppopoff
ppopoffppopoff
ppopoff
 
Elixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to ErlangElixir: the not-so-hidden path to Erlang
Elixir: the not-so-hidden path to Erlang
 
Functional programming's relentless bug hunter claire
Functional programming's relentless bug hunter  claireFunctional programming's relentless bug hunter  claire
Functional programming's relentless bug hunter claire
 
An Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End DevelopersAn Introduction to the World of Testing for Front-End Developers
An Introduction to the World of Testing for Front-End Developers
 
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
Bye Bye Charles, Welcome Odo, Android Meetup Berlin May 2014
 
Android testing
Android testingAndroid testing
Android testing
 
Stuff you didn't know about action script
Stuff you didn't know about action scriptStuff you didn't know about action script
Stuff you didn't know about action script
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Swift 2
Swift 2Swift 2
Swift 2
 
Twins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional ProgrammingTwins: Object Oriented Programming and Functional Programming
Twins: Object Oriented Programming and Functional Programming
 
Don't do this
Don't do thisDon't do this
Don't do this
 
Thirteen ways of looking at a turtle
Thirteen ways of looking at a turtleThirteen ways of looking at a turtle
Thirteen ways of looking at a turtle
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Akka in-action
Akka in-actionAkka in-action
Akka in-action
 

Similar to Property based tests and where to find them - Andrzej Jóźwiak - TomTom Webinar June 2020

New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxTest-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxVictor Rentea
 
Factories, mocks and spies: a tester's little helpers
Factories, mocks and spies: a tester's little helpersFactories, mocks and spies: a tester's little helpers
Factories, mocks and spies: a tester's little helperstxels
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
 
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...Andrzej Jóźwiak
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMockYing Zhang
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit TestingDmitry Vyukov
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and ProsperKen Kousen
 
Finding bugs that matter with Findbugs
Finding bugs that matter with FindbugsFinding bugs that matter with Findbugs
Finding bugs that matter with FindbugsCarol McDonald
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEAHamletDRC
 
Android Unit Test
Android Unit TestAndroid Unit Test
Android Unit TestPhuoc Bui
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctlyDror Helper
 
White-box Unit Test Generation with Microsoft IntelliTest
White-box Unit Test Generation with Microsoft IntelliTestWhite-box Unit Test Generation with Microsoft IntelliTest
White-box Unit Test Generation with Microsoft IntelliTestDávid Honfi
 
An Introduction to Property Based Testing
An Introduction to Property Based TestingAn Introduction to Property Based Testing
An Introduction to Property Based TestingC4Media
 
1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx
 1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx 1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx
1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docxaryan532920
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...Holden Karau
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 

Similar to Property based tests and where to find them - Andrzej Jóźwiak - TomTom Webinar June 2020 (20)

New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxTest-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
 
Factories, mocks and spies: a tester's little helpers
Factories, mocks and spies: a tester's little helpersFactories, mocks and spies: a tester's little helpers
Factories, mocks and spies: a tester's little helpers
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...
JUnit 4 Can it still teach us something? - Andrzej Jóźwiak - Kariera IT Łodź ...
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMock
 
Unit testing - A&BP CC
Unit testing - A&BP CCUnit testing - A&BP CC
Unit testing - A&BP CC
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
 
Finding bugs that matter with Findbugs
Finding bugs that matter with FindbugsFinding bugs that matter with Findbugs
Finding bugs that matter with Findbugs
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
Android Unit Test
Android Unit TestAndroid Unit Test
Android Unit Test
 
Building unit tests correctly
Building unit tests correctlyBuilding unit tests correctly
Building unit tests correctly
 
White-box Unit Test Generation with Microsoft IntelliTest
White-box Unit Test Generation with Microsoft IntelliTestWhite-box Unit Test Generation with Microsoft IntelliTest
White-box Unit Test Generation with Microsoft IntelliTest
 
An Introduction to Property Based Testing
An Introduction to Property Based TestingAn Introduction to Property Based Testing
An Introduction to Property Based Testing
 
1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx
 1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx 1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx
1 COMP 182 Fall 2016 Project 6 Binary Search Trees .docx
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...Testing and validating distributed systems with Apache Spark and Apache Beam ...
Testing and validating distributed systems with Apache Spark and Apache Beam ...
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 

More from Andrzej Jóźwiak

Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...
Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...
Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...Andrzej Jóźwiak
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Andrzej Jóźwiak
 
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...Andrzej Jóźwiak
 
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021Andrzej Jóźwiak
 
Types of Randomness in Game Design - Rapid Talks - December 2020
Types of Randomness in Game Design - Rapid Talks - December 2020Types of Randomness in Game Design - Rapid Talks - December 2020
Types of Randomness in Game Design - Rapid Talks - December 2020Andrzej Jóźwiak
 
Capability Driven Design - Rapid Talks - November 2020
Capability Driven Design - Rapid Talks - November 2020Capability Driven Design - Rapid Talks - November 2020
Capability Driven Design - Rapid Talks - November 2020Andrzej Jóźwiak
 
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Andrzej Jóźwiak
 

More from Andrzej Jóźwiak (7)

Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...
Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...
Encapsulation – the pitfalls of Object-Oriented Programming - Andrzej Jóźwiak...
 
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
Does testability imply good design - Andrzej Jóźwiak - TomTom Dev Day 2022
 
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...
Introduction to the Kotlin programming language - Andrzej Jóźwiak - JUG Łódź ...
 
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021Capability Driven Design - Andrzej Jóźwiak  - TomTom Dev Day 2021
Capability Driven Design - Andrzej Jóźwiak - TomTom Dev Day 2021
 
Types of Randomness in Game Design - Rapid Talks - December 2020
Types of Randomness in Game Design - Rapid Talks - December 2020Types of Randomness in Game Design - Rapid Talks - December 2020
Types of Randomness in Game Design - Rapid Talks - December 2020
 
Capability Driven Design - Rapid Talks - November 2020
Capability Driven Design - Rapid Talks - November 2020Capability Driven Design - Rapid Talks - November 2020
Capability Driven Design - Rapid Talks - November 2020
 
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
Do I need tests when I have the compiler - Andrzej Jóźwiak - TomTom Dev Day 2020
 

Recently uploaded

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 

Recently uploaded (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 

Property based tests and where to find them - Andrzej Jóźwiak - TomTom Webinar June 2020

  • 3. Exploits of a Mom: https://xkcd.com/327/ 3
  • 4. Poll: Unit tests ... A. are exhaustive B. guarantee the correctness C. help find unknown cases D. all of the above E. it really depends on the context 4
  • 5. Would you like to play a game? Can your unit tests ... 5
  • 6. find out that the car brakes do not work when volume on the radio is changed? Can your unit tests ... Experiences with QuickCheck: https://www.cs.tufts.edu/~nr/cs257/archive/john-hughes/quviq-testing.pdf 6
  • 7. Bypassing Android lockscreen: https://sites.utexas.edu/iso/2015/09/15/android-5-lockscreen-bypass/ find out that putting enough text in the Android lock screen text field can crash it and give full access to the phone? Can your unit tests ... 7
  • 8. A Formal Specification of a File Synchronizer: https://www.cis.upenn.edu/~bcpierce/papers/unisonspec.pdf find out that your secure file storage is not secure and is losing data? Can your unit tests ... 8
  • 9. find out that going back and forth through a list of available voices can cause the app to play an incorrect voice? Can your unit tests ... my own child sure can! 9 This is a thing that we found out in our own app
  • 10. 10 Twitter: https://twitter.com/cbirchall/status/1209156343904587779 All unit tests passing do not always guarantee correctness...
  • 11. 11 And now for an academic example... public static <A> List<A> reverse(final List<A> original) { final int size = original.size(); final List<A> reversed = new ArrayList<>(size); // going from the last element to the first of the original list for (int i = size - 1; i >= 0; i--) { // thus adding the elements in the reversed order reversed.add(original.get(i)); } return reversed; } What are the properties of the code here? Github: https://git.io/JfDGP
  • 12. 12 Lists reverse function example based tests Github: https://git.io/JfDGa
  • 13. 13 Let’s build an example property... Github: https://git.io/JfDZS @Test public void reverse_reversed_equals_original() { // given: final List<String> tested = Arrays.asList("This", "is", "a", "test"); // when: final List<String> result = reverse(reverse(tested)); // then: assertEquals(tested, result); // Should we create more examples? }
  • 14. 14 Let’s build a property based testing framework ... We will notice soon enough that something is missing
  • 15. 15 Let’s build a property based testing framework ... private interface Property<A> { boolean check(A value); } private static <A> Property<List<A>> reverseOfReversedEqualsOriginal () { return original -> reverse(reverse(original)).equals(original); } Github: https://git.io/JfDZS
  • 16. 16 Let’s build a property based testing framework ... private interface Generator<A> { A generate(Random seed); } // A very simple generator that produces lists: // - with size varying from 0 to 100 // - with elements being numbers from 0 to 100 as strings private Generator<List<String>> randomStringListsGenerator () { return seed -> { final int randomSize = randInt(seed, 0, 100); final List<String> randomizedList = new ArrayList<>(randomSize); for (int i = 0; i < randomSize; i++) { randomizedList .add(String.valueOf(randInt(seed, 0, 100))); } return randomizedList ; }; } Github: https://git.io/JfDZS
  • 17. 17 Let’s build a property based testing framework ... private static <A> void quickCheck(final long seedValue, final int numberOfTries, final Property<A> property, final Generator<A> generator) { final Random seed = new Random(seedValue); for (int i = 0; i < numberOfTries; i++) { final A tested = generator.generate(seed); final boolean result = property.check(tested); if (!result) { final StringBuilder builder = new StringBuilder() .append("Property test failed") .append("nSeed value: ") .append(seedValue) .append("nExample data: ") .append(tested); throw new AssertionError(builder); } } } Github: https://git.io/JfDZS
  • 18. 18 Let’s build a property based testing framework ... @Test public void custom_reverse_property_test() { final int numberOfTries = 1000; final long seedValue = new Random().nextLong(); final Property<List<String>> reverseProperty = reverseOfReversedEqualsOriginal(); final Generator<List<String>> generator = randomStringListsGenerator(); quickCheck(seedValue, numberOfTries, reverseProperty, generator); } Github: https://git.io/JfDZS
  • 19. 19 We are lucky! The example only has 19 elements, what would happen if it had 1000 or 10000 elements? private static <A> Property<List<A>> reverseWrongProperty() { return original -> reverse(original).equals(original); } Github: https://git.io/JfDZS java.lang.AssertionError: Property test failed Seed value: -2569510089704470893 Example data: [40, 15, 20, 30, 36, 35, 55, 99, 89, 93, 67, 27, 31, 95, 26, 6, 84, 23, 92] How can we know our little framework is correct?
  • 20. 20 What about a professional solution? Github: https://git.io/JfDZS @Property @Report(Reporting.GENERATED) public boolean broken_reverse_property (@ForAll List<?> original) { return Lists.reverse(original).equals(original); } |-------------------jqwik------------------- tries = 1 | # of calls to property checks = 1 | # of not rejected calls generation-mode = RANDOMIZED | parameters are randomly generated after-failure = PREVIOUS_SEED | use the previous seed seed = -1616208483702989146 | random seed to reproduce generated values sample = [[Any[0], Any[1]]] original-sample = [[Any[64], Any[226], Any[319], Any[71], Any[351], Any[137], Any[9], Any[262], Any[239], Any[485], Any[23], Any[265], Any[108], Any[348], Any[202], Any[365], Any[147], Any[347], Any[133]]] It also found a 19 element example but managed to shrink it to 2
  • 21. 21 Poll: Our framework was missing ... A. a way to shrink the example to smallest possible size B. a way to shrink the values used by the example C. pretty printing of the output D. all of the above E. nothing, It was perfect! F. I bet there is something more!
  • 22. 22 Our framework was missing ...
  • 23. Are there well established categories of properties? 23 Before we leave the realm of academic examples... and the Math behind them is minimal! I promise.
  • 25. 25 Property Category: Encode/Decode Twitter: https://github.com/btlines/pbdirect
  • 26. 26 Property Category: Encode/Decode Twitter: https://github.com/btlines/pbdirect
  • 28. 28 Property Category: Invariants size of the collection: some operations on collections do not change their size but only modify the order of elements or their state like sorting, mapping content of the collection: some operations on collections do not change their content (do not remove or add elements), it’s possible to find all elements but just in a different order order of elements: some operations change the characteristics of elements but do not change their order domain specific: premium users will always have a special discount regardless of the amount of items on their shopping cart. We can always find properties of our model that do not changed regardless of operations applied.
  • 30. 30 Property Category: Idempotence absolute value of an integer: abs(abs(x)) = abs(x) floor, ceiling functions: ceil(ceil(x)) = ceil(x) database search: searching for an element in a database multiple times should give us the same results each time. This only holds in a case where there are no updates in between. sorting: sorting a collection multiple times should give us the same result, sorting an already sorted collection should give us the same result, the same applies for filtering, searching for distinct elements etc. crosswalk button: pressing a crosswalk button multiple times will not change the end result of the lights changing from red to green.
  • 31. 31 Property Category: Different paths lead to the same destination
  • 32. 32 Property Category: Different paths lead to the same destination commutative property of addition: x + y = y + x, for all x, y ∈ R putting socks on your feet: does it matter in which order we will put our socks on? If the thing that we would like end up with are both feet in socks, then it does not matter if we start with left or right foot! applying discount code to the shopping cart: does it matter if we apply the discount code to an empty cart (ofc if the API allows to start shopping like this) before we add the items? The result should be the same for when we apply the discount to already filled shopping cart. putting ingredients on your pizza: does it matter if we start with pineapple or ham if we want to have great pizza? I know I know this example is controversial! filtering and sorting the results: the end result should be the same if we start from sorting and then filter out the unwanted results. Let’s not focus on the issue of optimization
  • 34. 34 Property Category: Test Oracle result should stay the same: code after refactoring should give the same results as the original one for the same input. This can be applied for any kind of code not only examples like sorting or filtering. If we are reworking some UI elements to support new cases it should behave the same like the old one for all old cases. the new algorithm should not have worse performance then the old one: if the refactored code should use less memory, use less hard drive space, perform less operations, in other words just be better in some way or at least not worse, then comparing old with new is the way to go. when writing a property is not obvious: instead of finding a property of the code like encode/decode or different paths same result, we can base our tests on the already existing code and its results.
  • 35. OK. Everything is nice but I am not writing sorting for my day job! 35 Now off to the real world... or reverse, or map, or json encoding for that matter
  • 36. 36 1. open new database 2. put key1 and val1 3. close database 4. open database 5. delete key2 6. delete key1 7. close database 8. open database 9. delete key2 10. close database 11. open database 12. put key3 and val1 13. close database 14. open database 15. close database 16. open database 17. seek first Expected output? key3 Actual output? key1 Reappearing "ghost" key after 17 steps: https://github.com/google/leveldb/issues/50 A ghost story ... Would you come up with such an example?
  • 37. 37 Reappearing "ghost" key after 17 steps: https://github.com/google/leveldb/issues/50 A ghost story - a rehaunting ... After a patch that was supposedly fixing the issue a new example was found this time made up from 33 steps. After almost a month it was finally fixed. Fixed bug in picking inputs for a level-0 compaction. When finding overlapping files, the covered range may expand as files are added to the input set. We now correctly expand the range when this happens instead of continuing to use the old range. This change fixes a bug related to deleted keys showing up incorrectly after a compaction.
  • 39. 39 Stateful testing... Model - describes the current expected state of the system. Often we know what to expect from the code, it does not matter how the code gets to that result. Commands - represent what the system under test should do, command generation needs to take into account the current model state. Validation - way to check the current model state and compare it with the system under test state. SUT - system under test, stateful in it’s nature
  • 40. 40 A stateful representation of a shopping cart ... public class ShoppingCart { public Quantity get(Product product) public List<Product> getAllProducts () public Quantity add(Product product, Quantity quantity) public Quantity remove(Product product, Quantity quantity) public void clear() public void setDiscount(DiscountCode code) public void clearDiscount() public Price getTotalPrice() public Quantity getTotalQuantity () }
  • 41. 41 A simplified shopping cart model ... public class ShoppingCartModel { private List<ShoppingCartModelElement> products = new LinkedList<>(); private int discount = 0; //% private static class ShoppingCartModelElement { public String product; public int price; public int quantity; } }
  • 42. 42 A simplified representation of a command in our system ... public interface Command<M, S> { boolean preconditions(final M model); void execute(final M model, final S sut); void postconditions (final M model, final S sut); }
  • 43. 43 An implementation of one of the available commands ... public class AddProductCommand implements Command<ShoppingCartModel , ShoppingCart > { public void execute(final ShoppingCartModel model, final ShoppingCart sut) { model.addProduct( product .getName(), quantity .getValue(), product .getPrice().getValue() ); sut.add( product, quantity); } public void postconditions (final ShoppingCartModel model, final ShoppingCart sut) { Assertions.assertEquals( model.getQuantity( product.getName()), sut.get( product).getValue() ); }
  • 44. 44 Available commands for our property test - AddProductCommand - RemoveProductCommand - GetProductCommand - GetAllProductsCommand - ClearProductCommand - ClearCommand - ClearProductCommand - SetDiscountCommand - ClearDiscountCommand - GetTotalPriceCommand - GetTotalQuantityCommand Now we need to create random sequences of commands that will stress the implementation of our stateful component.
  • 45. 45 Testing properties of a shopping cart ... Let’s introduce a bug in the shopping cart: - if the shopping carts has 3 or more elements - it will NOT add any more elements Run failed after following actions: AddProductCommand{ product=Product{name='AAA', price=Price(3)}, quantity=Quantity(1)} AddProductCommand{ product=Product{name='AAa', price=Price(3)}, quantity=Quantity(1)} AddProductCommand{ product=Product{name='ABA', price=Price(3)}, quantity=Quantity(1)} AddProductCommand{ product=Product{name='AAB', price=Price(3)}, quantity=Quantity(1)}
  • 46. 46 Testing properties of a shopping cart ... original-sample = [ActionSequence[FAILED]: [SetDiscountCommand{discount=Discount(58)}, GetTotalQuantityCommand{}, ClearCommand{}, SetDiscountCommand{discount=Discount(100)}, SetDiscountCommand{discount=Discount(58)}, GetTotalQuantityCommand{}, GetTotalPriceCommand{}, ClearDiscountCommand{}, SetDiscountCommand{discount=Discount(18)}, GetTotalQuantityCommand{}, GetTotalPriceCommand{}, ClearCommand{}, GetTotalQuantityCommand{}, AddProductCommand{ product=Product{name='ZzZaWB', price=Price(6)}, quantity=Quantity(60)}, GetTotalPriceCommand{}, AddProductCommand{ product=Product{name='zEfaZZga', price=Price(8)}, quantity=Quantity(74)}, GetTotalPriceCommand{}, ClearDiscountCommand{}, AddProductCommand{ product=Product{name='faGZQAGAQ', price=Price(9)}, quantity=Quantity(154)}, GetTotalQuantityCommand{}, AddProductCommand{ product=Product{name='ZVdJaj', price=Price(6)}, quantity=Quantity(66)}, SetDiscountCommand{discount=Discount(32)}, GetTotalQuantityCommand{}, GetTotalQuantityCommand{}, GetTotalQuantityCommand{}, AddProductCommand{ product=Product{name='AAzZza', price=Price(6)}, quantity=Quantity(5)}]]
  • 48. 48 Further reading: (book) PropEr Testing https://propertesting.com/toc.html (documentation) QuickCheck: https://hackage.haskell.org/package/QuickCheck (article) Introduction to PBT: https://fsharpforfunandprofit.com/posts/property-based-testing/ (documentation) jqwik: https://jqwik.net/ (presentation) Stateful PBT: https://www.youtube.com/watch?v=owHmYA52SIM (presentation) Don’t Write Tests: https://www.youtube.com/watch?v=hXnS_Xjwk2Y (presentation) Testing the Hard Stuff: https://www.youtube.com/watch?v=zi0rHwfiX1Q (examples): https://github.com/artificialrevelations/property-based-testing-workshop