SlideShare a Scribd company logo
1 of 93
QCon London 2016
An Introduction to Property Based Testing
Aaron Bedra
Chief Security Officer, Eligible
@abedra
InfoQ.com: News & Community Site
• 750,000 unique visitors/month
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• News 15-20 / week
• Articles 3-4 / week
• Presentations (videos) 12-15 / week
• Interviews 2-3 / week
• Books 1 / month
Watch the video with slide
synchronization on InfoQ.com!
http://www.infoq.com/presentations
/property-based-testing-2016
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Presented at QCon London
www.qconlondon.com
Why do we test?
• To better understand what we are building
• To help us think deeper about what we are building
• To ensure the correctness of what we are building
• To help us explore our design*
• To explain to others how our code should work
How do we test?
• With compilers (type systems, static analysis, etc)
• Manual testing
• X-Unit style tests
• Property/generative based tests
• Formal modeling
How do we test?
• With compilers (type systems, static analysis, etc)
• Manual testing
• X-Unit style tests
• Property/generative based tests
• Formal modeling
What is it?
An abstraction
Property based testing eliminates
the guess work on value and
order of operations testing
Magic numbers
Instead of specifying
how you specify what
Testing over time
When we start our test
suite, things are usually
easy to understand
public class Basic {
public static Integer calculate(Integer x, Integer y) {
return x + y;
}
}
public class BasicTest {
@Test
public void TestCalculate() {
assertEquals(Integer.valueOf(5), Basic.calculate(3, 2));
}
}
What other tests might
we write for this code?
Like all programs we
start simple
But over time things get
more complicated
What happens when our simple
calculate function grows to
include an entire domain?
Our test suite will undoubtedly
grow, but we have options to
control the growth
And also maintain
confidence in our tests
By changing our mental
model just a bit we can
cover much more ground
Let’s revisit our basic
example
public class Basic {
public static Integer calculate(Integer x, Integer y) {
return x + y;
}
}
But instead of a unit test,
let’s write a property
@RunWith(JUnitQuickcheck.class)
public class BasicProperties {
@Property public void calculateBaseAssumption(Integer x, Integer y) {
Integer expected = x + y;
assertEquals(expected, Basic.calculate(x, y));
}
}
public class BasicTest {
@Test
public void TestCalculate() {
assertEquals(Integer.valueOf(5), Basic.calculate(3, 2));
}
}
@RunWith(JUnitQuickcheck.class)
public class BasicProperties {
@Property(trials = 1000000) public void
calculateBaseAssumption(Integer x, Integer y) {
Integer expected = x + y;
assertEquals(expected, Basic.calculate(x, y));
}
}
This property isn’t much
different than the unit test
we had before it
It’s just one level of
abstraction higher
Let’s add a constraint to
our calculator
Let’s say that the output
cannot be negative
public class Basic {
public static Integer calculate(Integer x, Integer y) {
Integer total = x + y;
if (total < 0) {
return 0;
} else {
return total;
}
}
}
java.lang.AssertionError: Property calculateBaseAssumption falsified for args
shrunken to [0, -679447654]
Shrinking
@RunWith(JUnitQuickcheck.class)
public class BasicProperties {
@Property public void calculateBaseAssumption(Integer x, Integer y) {
Integer expected = x + y;
assertEquals(expected, Basic.calculate(x, y));
}
}
public class Basic {
public static Integer calculate(Integer x, Integer y) {
Integer total = x + y;
if (total < 0) {
return 0;
} else {
return total;
}
}
}
Now we can be more
specific with our property
@RunWith(JUnitQuickcheck.class)
public class BasicProperties {
@Property public void calculateBaseAssumption(Integer x, Integer y) {
assumeThat(x, greaterThan(0));
assumeThat(y, greaterThan(0));
assertThat(Basic.calculate(x, y), is(greaterThan(0)));
}
}
java.lang.AssertionError: Property calculateBaseAssumption falsified for args shrunken to [647853159,
1499681379]
We could keep going from
here but let’s dive into
some of the concepts
Refactoring
This is one of my favorite
use cases for invoking
property based testing
Legacy code becomes
the model
It’s incredibly powerful
It ensures you have
exact feature parity
Even for unintended
features!
Generators
You can use them for all
kinds of things
Scenario
Every route in your web
application
You could define
generators based on your
routes
And create valid and
invalid inputs for every
endpoint
You could run the
generators on every test
Or save the output of the
generation for faster
execution
Saved execution of
generators can even bring
you to simulation testing
There are tons of property
based testing libraries
available
But this is a talk in a
functional language track
So let’s have some fun
Let’s pretend we have
some legacy code
Written in C
And we want to test it to
make sure it actually
works
But there are no
quickcheck libraries
available*
Warning! The crypto you are
about to see should not be
attempted at work
Caesar’s Cipher
Let’s start with our
implementation
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *caesar(int shift, char *input)
{
char *output = malloc(strlen(input));
memset(output, '0', strlen(input));
for (int x = 0; x < strlen(input); x++) {
if (isalpha(input[x])) {
int c = toupper(input[x]);
c = (((c - 65) + shift) % 26) + 65;
output[x] = c;
} else {
output[x] = input[x];
}
}
return output;
}
Next we create a new
implementation to test
against
caesar :: Int -> String -> String
caesar k = map f
where
f c
| inRange ('A', 'Z') c = chr $ ord 'A' +
(ord c - ord 'A' + k) `mod` 26
| otherwise = c
We now have two
functions that “should” do
the same thing
But they aren’t in the
same language
Thankfully Haskell has
good FFI support
foreign import ccall "caesar.h caesar"
c_caesar :: CInt -> CString -> CString
native_caesar :: Int -> String -> IO String
native_caesar shift input = withCString input $ c_str ->
peekCString(c_caesar (fromIntegral shift) c_str)
$ stack exec ghci caesar.hs caesar.so
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( caesar.hs, interpreted )
Ok, modules loaded: Main.
*Main> caesar 2 "ATTACKATDAWN"
"CVVCEMCVFCYP"
*Main> native_caesar 2 "ATTACKATDAWN"
"CVVCEMCVFCYP"
We can now execute our
C code from inside of
Haskell
We can use Haskell’s
quickcheck library to
verify our C code
First we need to write a
property
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
unsafeEq :: IO String -> String -> Bool
unsafeEq x y = unsafePerformIO(x) == y
genSafeChar :: Gen Char
genSafeChar = elements ['A' .. 'Z']
genSafeString :: Gen String
genSafeString = listOf genSafeChar
newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show
instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString
equivalenceProperty = forAll genSafeString $ str ->
unsafeEq (native_caesar 2 str) (caesar 2 str)
*Main> quickCheck equivalenceProperty
*** Failed! Falsifiable (after 20 tests):
"QYMSMCWTIXNDFDMLSL"
*Main> caesar 2 "QYMSMCWTIXNDFDMLSL"
"SAOUOEYVKZPFHFONUN"
*Main> native_caesar 2 "QYMSMCWTIXNDFDMLSL"
“SAOUOEYVKZPFHFONUN/Users/abedra/x“
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *caesar(int shift, char *input)
{
char *output = malloc(strlen(input));
memset(output, '0', strlen(input));
for (int x = 0; x < strlen(input); x++) {
if (isalpha(input[x])) {
int c = toupper(input[x]);
c = (((c - 65) + shift) % 26) + 65;
output[x] = c;
} else {
output[x] = input[x];
}
}
return output;
}
We’ve found a memory
handling issue in our C
code!
In reality there are more
issues with this code, but our
issue was quickly exposed
And easily reproduced
Wrapping up
Not all testing is created
equal
You should use as many
different testing
techniques as you need
Remember to think about
the limits of your tools
And use tools that help
you achieve your results
more effectively
And more efficiently
Questions?
Watch the video with slide synchronization on
InfoQ.com!
http://www.infoq.com/presentations/property-
based-testing-2016

More Related Content

What's hot

Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightWiem Zine Elabidine
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Mario Fusco
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Datagreenwop
 
Beyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckBeyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckFranklin Chen
 
Learning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a NeckbeardKelsey Gilmore-Innis
 
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
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaWiem Zine Elabidine
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterScott Wlaschin
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Scott Wlaschin
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple ProgramsUpender Upr
 
An Introduction to Functional Programming - DeveloperUG - 20140311
An Introduction to Functional Programming - DeveloperUG - 20140311An Introduction to Functional Programming - DeveloperUG - 20140311
An Introduction to Functional Programming - DeveloperUG - 20140311Andreas Pauley
 

What's hot (20)

Zio from Home
Zio from Home Zio from Home
Zio from Home
 
Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnight
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Category theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) DataCategory theory, Monads, and Duality in the world of (BIG) Data
Category theory, Monads, and Duality in the world of (BIG) Data
 
Beyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheckBeyond xUnit example-based testing: property-based testing with ScalaCheck
Beyond xUnit example-based testing: property-based testing with ScalaCheck
 
Fiber supervision in ZIO
Fiber supervision in ZIOFiber supervision in ZIO
Fiber supervision in ZIO
 
07. Arrays
07. Arrays07. Arrays
07. Arrays
 
Learning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a NeckbeardLearning Functional Programming Without Growing a Neckbeard
Learning Functional Programming Without Growing a Neckbeard
 
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
 
ZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in ScalaZIO: Powerful and Principled Functional Programming in Scala
ZIO: Powerful and Principled Functional Programming in Scala
 
Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the Monadster
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
Friendly Functional Programming
Friendly Functional ProgrammingFriendly Functional Programming
Friendly Functional Programming
 
Akka tips
Akka tipsAkka tips
Akka tips
 
Java Simple Programs
Java Simple ProgramsJava Simple Programs
Java Simple Programs
 
An Introduction to Functional Programming - DeveloperUG - 20140311
An Introduction to Functional Programming - DeveloperUG - 20140311An Introduction to Functional Programming - DeveloperUG - 20140311
An Introduction to Functional Programming - DeveloperUG - 20140311
 

Viewers also liked

Advances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeAdvances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeTao Xie
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsAlexander Tarlinder
 
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsTesting at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsSauce Labs
 
JUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJohn Ferguson Smart Limited
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesDebasish Ghosh
 

Viewers also liked (6)

Advances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and PracticeAdvances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and Practice
 
Dealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring testsDealing with combinatorial explosions and boring tests
Dealing with combinatorial explosions and boring tests
 
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce LabsTesting at Yammer with FooUnit, Jellyfish, and Sauce Labs
Testing at Yammer with FooUnit, Jellyfish, and Sauce Labs
 
JUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit Tests
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 

Similar to An Introduction to Property Based Testing

Aaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security TeamsAaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security Teamscentralohioissa
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9Marcus Lagergren
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6Nitay Neeman
 
Javascript variables and datatypes
Javascript variables and datatypesJavascript variables and datatypes
Javascript variables and datatypesVarun C M
 
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
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
JavaScript(Es5) Interview Questions & Answers
JavaScript(Es5)  Interview Questions & AnswersJavaScript(Es5)  Interview Questions & Answers
JavaScript(Es5) Interview Questions & AnswersRatnala Charan kumar
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Paco de la Cruz
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
JavaScript Misunderstood
JavaScript MisunderstoodJavaScript Misunderstood
JavaScript MisunderstoodBhavya Siddappa
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdfHans Jones
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to JavascriptAnjan Banda
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 

Similar to An Introduction to Property Based Testing (20)

Aaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security TeamsAaron Bedra - Effective Software Security Teams
Aaron Bedra - Effective Software Security Teams
 
V8
V8V8
V8
 
A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9A new execution model for Nashorn in Java 9
A new execution model for Nashorn in Java 9
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6
 
Javascript variables and datatypes
Javascript variables and datatypesJavascript variables and datatypes
Javascript variables and datatypes
 
ppopoff
ppopoffppopoff
ppopoff
 
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
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
JavaScript(Es5) Interview Questions & Answers
JavaScript(Es5)  Interview Questions & AnswersJavaScript(Es5)  Interview Questions & Answers
JavaScript(Es5) Interview Questions & Answers
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)Durable functions 2.0 (2019-10-10)
Durable functions 2.0 (2019-10-10)
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
JavaScript Misunderstood
JavaScript MisunderstoodJavaScript Misunderstood
JavaScript Misunderstood
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
MT_01_unittest_python.pdf
MT_01_unittest_python.pdfMT_01_unittest_python.pdf
MT_01_unittest_python.pdf
 
Intro to Javascript
Intro to JavascriptIntro to Javascript
Intro to Javascript
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 

More from C4Media

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoC4Media
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileC4Media
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020C4Media
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsC4Media
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No KeeperC4Media
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like OwnersC4Media
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaC4Media
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideC4Media
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDC4Media
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine LearningC4Media
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at SpeedC4Media
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsC4Media
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsC4Media
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerC4Media
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleC4Media
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeC4Media
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereC4Media
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing ForC4Media
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data EngineeringC4Media
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreC4Media
 

More from C4Media (20)

Streaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live VideoStreaming a Million Likes/Second: Real-Time Interactions on Live Video
Streaming a Million Likes/Second: Real-Time Interactions on Live Video
 
Next Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy MobileNext Generation Client APIs in Envoy Mobile
Next Generation Client APIs in Envoy Mobile
 
Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020Software Teams and Teamwork Trends Report Q1 2020
Software Teams and Teamwork Trends Report Q1 2020
 
Understand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java ApplicationsUnderstand the Trade-offs Using Compilers for Java Applications
Understand the Trade-offs Using Compilers for Java Applications
 
Kafka Needs No Keeper
Kafka Needs No KeeperKafka Needs No Keeper
Kafka Needs No Keeper
 
High Performing Teams Act Like Owners
High Performing Teams Act Like OwnersHigh Performing Teams Act Like Owners
High Performing Teams Act Like Owners
 
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to JavaDoes Java Need Inline Types? What Project Valhalla Can Bring to Java
Does Java Need Inline Types? What Project Valhalla Can Bring to Java
 
Service Meshes- The Ultimate Guide
Service Meshes- The Ultimate GuideService Meshes- The Ultimate Guide
Service Meshes- The Ultimate Guide
 
Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 

Recently uploaded

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
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
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
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
 
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
 
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
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
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
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
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
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
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
 

Recently uploaded (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
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
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
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...
 
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
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
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
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
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...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
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...
 

An Introduction to Property Based Testing

  • 1. QCon London 2016 An Introduction to Property Based Testing Aaron Bedra Chief Security Officer, Eligible @abedra
  • 2. InfoQ.com: News & Community Site • 750,000 unique visitors/month • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • News 15-20 / week • Articles 3-4 / week • Presentations (videos) 12-15 / week • Interviews 2-3 / week • Books 1 / month Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations /property-based-testing-2016
  • 3. Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide Presented at QCon London www.qconlondon.com
  • 4. Why do we test? • To better understand what we are building • To help us think deeper about what we are building • To ensure the correctness of what we are building • To help us explore our design* • To explain to others how our code should work
  • 5. How do we test? • With compilers (type systems, static analysis, etc) • Manual testing • X-Unit style tests • Property/generative based tests • Formal modeling
  • 6. How do we test? • With compilers (type systems, static analysis, etc) • Manual testing • X-Unit style tests • Property/generative based tests • Formal modeling
  • 9. Property based testing eliminates the guess work on value and order of operations testing
  • 11. Instead of specifying how you specify what
  • 13. When we start our test suite, things are usually easy to understand
  • 14. public class Basic { public static Integer calculate(Integer x, Integer y) { return x + y; } }
  • 15. public class BasicTest { @Test public void TestCalculate() { assertEquals(Integer.valueOf(5), Basic.calculate(3, 2)); } }
  • 16. What other tests might we write for this code?
  • 17. Like all programs we start simple
  • 18. But over time things get more complicated
  • 19. What happens when our simple calculate function grows to include an entire domain?
  • 20. Our test suite will undoubtedly grow, but we have options to control the growth
  • 22.
  • 23. By changing our mental model just a bit we can cover much more ground
  • 24. Let’s revisit our basic example
  • 25. public class Basic { public static Integer calculate(Integer x, Integer y) { return x + y; } }
  • 26. But instead of a unit test, let’s write a property
  • 27. @RunWith(JUnitQuickcheck.class) public class BasicProperties { @Property public void calculateBaseAssumption(Integer x, Integer y) { Integer expected = x + y; assertEquals(expected, Basic.calculate(x, y)); } } public class BasicTest { @Test public void TestCalculate() { assertEquals(Integer.valueOf(5), Basic.calculate(3, 2)); } }
  • 28. @RunWith(JUnitQuickcheck.class) public class BasicProperties { @Property(trials = 1000000) public void calculateBaseAssumption(Integer x, Integer y) { Integer expected = x + y; assertEquals(expected, Basic.calculate(x, y)); } }
  • 29. This property isn’t much different than the unit test we had before it
  • 30. It’s just one level of abstraction higher
  • 31. Let’s add a constraint to our calculator
  • 32. Let’s say that the output cannot be negative
  • 33. public class Basic { public static Integer calculate(Integer x, Integer y) { Integer total = x + y; if (total < 0) { return 0; } else { return total; } } } java.lang.AssertionError: Property calculateBaseAssumption falsified for args shrunken to [0, -679447654]
  • 35. @RunWith(JUnitQuickcheck.class) public class BasicProperties { @Property public void calculateBaseAssumption(Integer x, Integer y) { Integer expected = x + y; assertEquals(expected, Basic.calculate(x, y)); } } public class Basic { public static Integer calculate(Integer x, Integer y) { Integer total = x + y; if (total < 0) { return 0; } else { return total; } } }
  • 36. Now we can be more specific with our property
  • 37. @RunWith(JUnitQuickcheck.class) public class BasicProperties { @Property public void calculateBaseAssumption(Integer x, Integer y) { assumeThat(x, greaterThan(0)); assumeThat(y, greaterThan(0)); assertThat(Basic.calculate(x, y), is(greaterThan(0))); } } java.lang.AssertionError: Property calculateBaseAssumption falsified for args shrunken to [647853159, 1499681379]
  • 38. We could keep going from here but let’s dive into some of the concepts
  • 40. This is one of my favorite use cases for invoking property based testing
  • 43. It ensures you have exact feature parity
  • 46. You can use them for all kinds of things
  • 48. Every route in your web application
  • 49. You could define generators based on your routes
  • 50. And create valid and invalid inputs for every endpoint
  • 51. You could run the generators on every test
  • 52. Or save the output of the generation for faster execution
  • 53. Saved execution of generators can even bring you to simulation testing
  • 54. There are tons of property based testing libraries available
  • 55. But this is a talk in a functional language track
  • 56. So let’s have some fun
  • 57. Let’s pretend we have some legacy code
  • 59. And we want to test it to make sure it actually works
  • 60. But there are no quickcheck libraries available*
  • 61. Warning! The crypto you are about to see should not be attempted at work
  • 63. Let’s start with our implementation
  • 64. #include <stdlib.h> #include <string.h> #include <ctype.h> char *caesar(int shift, char *input) { char *output = malloc(strlen(input)); memset(output, '0', strlen(input)); for (int x = 0; x < strlen(input); x++) { if (isalpha(input[x])) { int c = toupper(input[x]); c = (((c - 65) + shift) % 26) + 65; output[x] = c; } else { output[x] = input[x]; } } return output; }
  • 65. Next we create a new implementation to test against
  • 66. caesar :: Int -> String -> String caesar k = map f where f c | inRange ('A', 'Z') c = chr $ ord 'A' + (ord c - ord 'A' + k) `mod` 26 | otherwise = c
  • 67. We now have two functions that “should” do the same thing
  • 68. But they aren’t in the same language
  • 70. foreign import ccall "caesar.h caesar" c_caesar :: CInt -> CString -> CString native_caesar :: Int -> String -> IO String native_caesar shift input = withCString input $ c_str -> peekCString(c_caesar (fromIntegral shift) c_str)
  • 71. $ stack exec ghci caesar.hs caesar.so GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help [1 of 1] Compiling Main ( caesar.hs, interpreted ) Ok, modules loaded: Main. *Main> caesar 2 "ATTACKATDAWN" "CVVCEMCVFCYP" *Main> native_caesar 2 "ATTACKATDAWN" "CVVCEMCVFCYP"
  • 72. We can now execute our C code from inside of Haskell
  • 73. We can use Haskell’s quickcheck library to verify our C code
  • 74. First we need to write a property
  • 75. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 76. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 77. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 78. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 79. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 80. unsafeEq :: IO String -> String -> Bool unsafeEq x y = unsafePerformIO(x) == y genSafeChar :: Gen Char genSafeChar = elements ['A' .. 'Z'] genSafeString :: Gen String genSafeString = listOf genSafeChar newtype SafeString = SafeString { unwrapSafeString :: String } deriving Show instance Arbitrary SafeString where arbitrary = SafeString <$> genSafeString equivalenceProperty = forAll genSafeString $ str -> unsafeEq (native_caesar 2 str) (caesar 2 str)
  • 81. *Main> quickCheck equivalenceProperty *** Failed! Falsifiable (after 20 tests): "QYMSMCWTIXNDFDMLSL" *Main> caesar 2 "QYMSMCWTIXNDFDMLSL" "SAOUOEYVKZPFHFONUN" *Main> native_caesar 2 "QYMSMCWTIXNDFDMLSL" “SAOUOEYVKZPFHFONUN/Users/abedra/x“
  • 82. #include <stdlib.h> #include <string.h> #include <ctype.h> char *caesar(int shift, char *input) { char *output = malloc(strlen(input)); memset(output, '0', strlen(input)); for (int x = 0; x < strlen(input); x++) { if (isalpha(input[x])) { int c = toupper(input[x]); c = (((c - 65) + shift) % 26) + 65; output[x] = c; } else { output[x] = input[x]; } } return output; }
  • 83. We’ve found a memory handling issue in our C code!
  • 84. In reality there are more issues with this code, but our issue was quickly exposed
  • 87. Not all testing is created equal
  • 88. You should use as many different testing techniques as you need
  • 89. Remember to think about the limits of your tools
  • 90. And use tools that help you achieve your results more effectively
  • 93. Watch the video with slide synchronization on InfoQ.com! http://www.infoq.com/presentations/property- based-testing-2016