Thinking in Properties

Susan Potter
Susan PotterLead software engineer building distributed systems at Referential Labs, LLC
Thinking in Properties
And Beyond (Testing)
Susan Potter
2020-08-01
Intro
Intro
finger $(whoami)
• Introduced to QuickCheck in Erlang ~2010
• Adopted Haskell’s QuickCheck, Hedgehog, and ScalaCheck at work
• ”Testing” in production, thinking in properties, 4 years
Susan Potter Thinking in Properties 2020-08-01 1 / 41
Intro
Agenda
• An Origin Story (with code)
• Mental Models (above the code)
• Beyond Testing (illustrations)
Susan Potter Thinking in Properties 2020-08-01 2 / 41
An Origin Story
An Origin Story Discovering Superpowers
Susan Potter Thinking in Properties 2020-08-01 3 / 41
An Origin Story Discovering Superpowers
Explore domain with types
data List a = EmptyList | Cons a (List a)
type Pred a = (a -> Bool)
type Comp a = (a -> a -> Ordering)
sortBy :: Comp a -> List a -> List a
filter :: Pred a -> List a -> List a
reverse :: List a -> List a
last, first :: List a -> Maybe a
Susan Potter Thinking in Properties 2020-08-01 3 / 41
An Origin Story Discovering Superpowers
Explore domain with usage examples
-- | Reverse the elements of a list
-- >>> reverse (Cons 1 (Cons 2 (Cons 3
EmptyList)))→
-- Cons 3 (Cons 2 (Cons 1 EmptyList))
--
-- >>> reverse EmptyList
-- EmptyList
reverse :: List a -> List a
Susan Potter Thinking in Properties 2020-08-01 4 / 41
An Origin Story Discovering Superpowers
Encode examples as re-runnable tests
describe "Lib.reverse" $ do
it "returns [5,4,3,2,1] given [1,2,3,4,5]" $ do
reverse [1,2,3,4,5] `shouldBe` [5,4,3,2,1]
it "returns empty list given empty list" $ do
reverse [] `shouldBe` []
Susan Potter Thinking in Properties 2020-08-01 5 / 41
An Origin Story Discovering Superpowers
Rinse & Repeat
Susan Potter Thinking in Properties 2020-08-01 6 / 41
An Origin Story Discovering Superpowers
Continuous Learning
Figure 1: Schedule for Erlang Factory SF 2011 where my mind was blown
Susan Potter Thinking in Properties 2020-08-01 7 / 41
An Origin Story Harnessing Newly Found Superpowers
Characteristics of property-based testing
Where we have:
• generators that produce random ”arbitrary” values for inputs
• general rules that hold without knowing inputs upfront
• shrinking of failed values
• test runs assert rule multiple times using new generated values
Related terms: generative testing, fuzz testing (or ”fuzzing”)
Susan Potter Thinking in Properties 2020-08-01 8 / 41
An Origin Story Harnessing Newly Found Superpowers
Characteristics of property-based testing
Where we have:
• generators that produce random ”arbitrary” values for inputs
• general rules that hold without knowing inputs upfront
• shrinking of failed values
• test runs assert rule multiple times using new generated values
Related terms: generative testing, fuzz testing (or ”fuzzing”)
Susan Potter Thinking in Properties 2020-08-01 8 / 41
An Origin Story Harnessing Newly Found Superpowers
Characteristics of property-based testing
Where we have:
• generators that produce random ”arbitrary” values for inputs
• general rules that hold without knowing inputs upfront
• shrinking of failed values
• test runs assert rule multiple times using new generated values
Related terms: generative testing, fuzz testing (or ”fuzzing”)
Susan Potter Thinking in Properties 2020-08-01 8 / 41
An Origin Story Harnessing Newly Found Superpowers
Characteristics of property-based testing
Where we have:
• generators that produce random ”arbitrary” values for inputs
• general rules that hold without knowing inputs upfront
• shrinking of failed values
• test runs assert rule multiple times using new generated values
Related terms: generative testing, fuzz testing (or ”fuzzing”)
Susan Potter Thinking in Properties 2020-08-01 8 / 41
An Origin Story Harnessing Newly Found Superpowers
One General Rule: Round-tripping (two rides gets us back home)
Examples:
-- Assumes x is encodable and decodable
roundtrip0 = x -> decode (encode x) == Just x
roundtrip1 = x -> decodeBase64 (encodeBase64 x) == Right x
Counter-examples:
• sha256 is one way!
Susan Potter Thinking in Properties 2020-08-01 9 / 41
An Origin Story Harnessing Newly Found Superpowers
Introducing generators
To make these ideas concrete we will be using hedgehog with these imports:
import Hedgehog
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
import Control.Monad (replicateM)
import Data.Function (($), (.))
Hedgehog integrates shrinking with generation. We will not discuss this difference to QuickCheck but read Well Typed’s blog post about this here.
Susan Potter Thinking in Properties 2020-08-01 10 / 41
An Origin Story Harnessing Newly Found Superpowers
Primitive generators by example
>>> replicateM 25 $ Gen.sample Gen.lower
"okohcpxrkfunkmwnqujnnhxkg"
>>> let currencies = [ "USD", "JPY", "EUR", "CHF", "CNY" ]
>>> replicateM 5 $ Gen.sample $ Gen.element currencies
["USD","CNY","USD","JPY","USD"]
>>> replicateM 5 $ Gen.sample $ Gen.choice [ Gen.ascii,
Gen.unicode ]→
['f', 'c', 'j', '1068213', '<']
Susan Potter Thinking in Properties 2020-08-01 11 / 41
An Origin Story Harnessing Newly Found Superpowers
Generating your domain’s data, 1/2
Suppose our domain looks like this:
import Data.Word (Word8, Word16)
type W16 = Word16
data IP
= IPv4 Word8 Word8 Word8 Word8
| IPv6 W16 W16 W16 W16 W16 W16 W16 W16
Susan Potter Thinking in Properties 2020-08-01 12 / 41
An Origin Story Harnessing Newly Found Superpowers
Generating your domain’s data, 2/2
genW8 = Gen.word8 Range.constantBounded
genW16 = Gen.word16 Range.constantBounded
genIPv4 = IPv4 <$> genW8 <*> genW8 <*> genW8 <*> genW8
genIPv6 = IPv6 <$> genW16 <*> genW16 <*> genW16 <*> genW16
<*> genW16 <*> genW16 <*> genW16 <*> genW16
genAnyIP = Gen.choice [ genIPv4, genIPv6 ]
sampleIPs n = replicateM n (Gen.sample genAnyIP)
Susan Potter Thinking in Properties 2020-08-01 13 / 41
An Origin Story Harnessing Newly Found Superpowers
Sampling generated domain data
>>> sampleIPs 3
[ "136.59.149.200"
, "338d:2397:f612:e036:b27c:2298:4db8:b933"
, "5.38.65.204" ]
Susan Potter Thinking in Properties 2020-08-01 14 / 41
An Origin Story Harnessing Newly Found Superpowers
Writing Our First Property!
genList :: MonadGen m => m a -> m [a]
genList = Gen.list (Range.linear 0 1000)
genInt = Gen.int (Range.linear 0 100000)
-- "round-tripping" property
prop_reverse_reverse = property $ do
xs <- forAll $ genList genInt
Lib.reverse (Lib.reverse xs) === xs
Susan Potter Thinking in Properties 2020-08-01 15 / 41
An Origin Story Harnessing Newly Found Superpowers
Reviewing Our First Property!
Questions about prop_reverse_reverse:
• Does it assert anything about reverse ’s specification?
• Do callers of reverse need to exploit ”round-tripping”?
• Does an implementation exist that typechecks yet fails this property?
• Are we generating interesting data given the operation’s type?
• Are we resigned to function-level property testing?
Susan Potter Thinking in Properties 2020-08-01 16 / 41
An Origin Story Harnessing Newly Found Superpowers
Reviewing Our First Property!
Questions about prop_reverse_reverse:
• Does it assert anything about reverse ’s specification?
• Do callers of reverse need to exploit ”round-tripping”?
• Does an implementation exist that typechecks yet fails this property?
• Are we generating interesting data given the operation’s type?
• Are we resigned to function-level property testing?
Susan Potter Thinking in Properties 2020-08-01 16 / 41
An Origin Story Harnessing Newly Found Superpowers
Reviewing Our First Property!
Questions about prop_reverse_reverse:
• Does it assert anything about reverse ’s specification?
• Do callers of reverse need to exploit ”round-tripping”?
• Does an implementation exist that typechecks yet fails this property?
• Are we generating interesting data given the operation’s type?
• Are we resigned to function-level property testing?
Susan Potter Thinking in Properties 2020-08-01 16 / 41
An Origin Story Harnessing Newly Found Superpowers
Reviewing Our First Property!
Questions about prop_reverse_reverse:
• Does it assert anything about reverse ’s specification?
• Do callers of reverse need to exploit ”round-tripping”?
• Does an implementation exist that typechecks yet fails this property?
• Are we generating interesting data given the operation’s type?
• Are we resigned to function-level property testing?
Susan Potter Thinking in Properties 2020-08-01 16 / 41
An Origin Story Harnessing Newly Found Superpowers
Reviewing Our First Property!
Questions about prop_reverse_reverse:
• Does it assert anything about reverse ’s specification?
• Do callers of reverse need to exploit ”round-tripping”?
• Does an implementation exist that typechecks yet fails this property?
• Are we generating interesting data given the operation’s type?
• Are we resigned to function-level property testing?
Susan Potter Thinking in Properties 2020-08-01 16 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Example-based tests over time
t ~ 0 → t → ∞
Quick ⌣ →  / ⌢
Coverage ? →  / ⌢
Repeatable ⌣ →  / ⌢
Documents usage  →  / ⌢
Documents contract ⌢ → ⌢
Effort  →  / ⌢
• can measure coverage
• fixtures provide test data
• interesting fixtures brittle
• over time tends to ⌢
Susan Potter Thinking in Properties 2020-08-01 17 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Example-based tests over time
t ~ 0 → t → ∞
Quick ⌣ →  / ⌢
Coverage ? →  / ⌢
Repeatable ⌣ →  / ⌢
Documents usage  →  / ⌢
Documents contract ⌢ → ⌢
Effort  →  / ⌢
• can measure coverage
• fixtures provide test data
• interesting fixtures brittle
• over time tends to ⌢
Susan Potter Thinking in Properties 2020-08-01 17 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Example-based tests over time
t ~ 0 → t → ∞
Quick ⌣ →  / ⌢
Coverage ? →  / ⌢
Repeatable ⌣ →  / ⌢
Documents usage  →  / ⌢
Documents contract ⌢ → ⌢
Effort  →  / ⌢
• can measure coverage
• fixtures provide test data
• interesting fixtures brittle
• over time tends to ⌢
Susan Potter Thinking in Properties 2020-08-01 17 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Example-based tests over time
t ~ 0 → t → ∞
Quick ⌣ →  / ⌢
Coverage ? →  / ⌢
Repeatable ⌣ →  / ⌢
Documents usage  →  / ⌢
Documents contract ⌢ → ⌢
Effort  →  / ⌢
• can measure coverage
• fixtures provide test data
• interesting fixtures brittle
• over time tends to ⌢
Susan Potter Thinking in Properties 2020-08-01 17 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Example-based tests over time
t ~ 0 → t → ∞
Quick ⌣ →  / ⌢
Coverage ? →  / ⌢
Repeatable ⌣ →  / ⌢
Documents usage  →  / ⌢
Documents contract ⌢ → ⌢
Effort  →  / ⌢
• can measure coverage
• fixtures provide test data
• interesting fixtures brittle
• over time tends to ⌢
Susan Potter Thinking in Properties 2020-08-01 17 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Property-based tests initially
t ~ 0
Quick ⌣
Coverage ⌣
Repeatable ⌣
Documents usage 
Documents contract ⌣ / 
Effort ?
• Can we measure coverage ?
• We need to maintain generators
instead of fixtures!
• Not constrained by imagination! ⌣
• Am I smart enough to think up relevant
and meaningful properties ?
Susan Potter Thinking in Properties 2020-08-01 18 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Property-based tests initially
t ~ 0
Quick ⌣
Coverage ⌣
Repeatable ⌣
Documents usage 
Documents contract ⌣ / 
Effort ?
• Can we measure coverage ?
• We need to maintain generators
instead of fixtures!
• Not constrained by imagination! ⌣
• Am I smart enough to think up relevant
and meaningful properties ?
Susan Potter Thinking in Properties 2020-08-01 18 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Property-based tests initially
t ~ 0
Quick ⌣
Coverage ⌣
Repeatable ⌣
Documents usage 
Documents contract ⌣ / 
Effort ?
• Can we measure coverage ?
• We need to maintain generators
instead of fixtures!
• Not constrained by imagination! ⌣
• Am I smart enough to think up relevant
and meaningful properties ?
Susan Potter Thinking in Properties 2020-08-01 18 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Property-based tests initially
t ~ 0
Quick ⌣
Coverage ⌣
Repeatable ⌣
Documents usage 
Documents contract ⌣ / 
Effort ?
• Can we measure coverage ?
• We need to maintain generators
instead of fixtures!
• Not constrained by imagination! ⌣
• Am I smart enough to think up relevant
and meaningful properties ?
Susan Potter Thinking in Properties 2020-08-01 18 / 41
An Origin Story Harnessing Newly Found Superpowers
Quick Review: Property-based tests initially
t ~ 0
Quick ⌣
Coverage ⌣
Repeatable ⌣
Documents usage 
Documents contract ⌣ / 
Effort ?
• Can we measure coverage ?
• We need to maintain generators
instead of fixtures!
• Not constrained by imagination! ⌣
• Am I smart enough to think up relevant
and meaningful properties ?
Susan Potter Thinking in Properties 2020-08-01 18 / 41
Mental Models
Mental Models
Deriving Properties: Algebraic laws
Law What might it be good for
Idempotency e.g. event log effects, REST APIs, config effects
Associativity e.g. map/reduce distribution
Commutativity e.g. map/reduce local parallelism
Distributivity e.g. stable or performant rewrite rules
Identity element e.g. for invariance at that value for operation
Round-tripping e.g. encoding/decoding
Absorption e.g. boolean algebra rewrites
Transitivity e.g. dependency closures
Susan Potter Thinking in Properties 2020-08-01 19 / 41
Mental Models
Algebraic laws: Idempotency (running 1+ times yields same result)
Examples:
idem0 = x -> abs x == abs (abs x)
idem2 = x -> toUpper s == toUpper (toUpper s)
• curl -XPUT https://foo.bar/resource/123 -d baz=qux
Counter-example:
• curl -XPOST https://foo.bar/resource -d baz=qux
Algebra:
Given x ∈ A and f ∈ (A → A) and f(x) = f(f(x)) then f is idempotent.
Susan Potter Thinking in Properties 2020-08-01 20 / 41
Mental Models
Algebraic laws: Associativity (brackets to the left or right)
Examples:
assoc0 = x y z -> (x + y) + z == x + (y + z)
assoc1 = x y z -> (x ++ y) ++ z == x ++ (y ++ z)
Counter-example:
• (x − y) − z = x − (y − z)
Algebra:
Given x, y, z ∈ A, ⊕ ∈ (A → A → A) and (x ⊕ y) ⊕ z = x ⊕ (y ⊕ z) then ⊕ is
associative.
Susan Potter Thinking in Properties 2020-08-01 21 / 41
Mental Models
Algebraic laws: Commutativity (any order will do)
Examples:
comm0 = x y -> x + y == y + x
comm1 = x y -> x * y == y * x
Counter-example:
• x + +y = y + +x
• x − y = y − x
Algebra:
Given x, y ∈ A, ⊕ ∈ (A → A → A) and $x ⊕ y = y ⊕x then ⊕ is commutative.
Susan Potter Thinking in Properties 2020-08-01 22 / 41
Mental Models
Algebraic laws: Distributivity (one operation over another)
Examples:
dist0 = x y z -> x*(y + z) == x*y + x*z
Counter-example:
• x + (y ∗ z) = x + y ∗ x + z where x = 1, y = 2, z = 3
1 + (2 ∗ 3) = 1 + 2 ∗ 1 + 3 ⇒ 7 = 6
Algebra:
Given x, y, z ∈ A and ⊕, ⊗ ∈ (A → A → A) then ⊗ is distributive over ⊕ when
x ⊗ (y ⊕ z) = x ⊗ y ⊕ x ⊗ z
Susan Potter Thinking in Properties 2020-08-01 23 / 41
Mental Models
Algebraic laws: Identity element
Examples:
identity0 = x -> 0 + x == x
identity1 = x -> False || x == x
identity2 = s -> "" ++ s == s
Counter-example:
-NonEmpty does not have an identity element
Algebra:
∃e ∈ A, ∀a ∈ A, e ⊕ a = a then e is the identity element in A.
Susan Potter Thinking in Properties 2020-08-01 24 / 41
Mental Models
Algebraic laws: Absorption
Examples:
absorption0 = a b -> (a || (a && b)) == a
absorption1 = a b -> (a && (a || b)) == a
Algebra: Given ∧, ∨ ∈ (A → A → A) and a, b ∈ A then when
a ∧ (a ∨ b) = a = a ∨ (a ∧ b)
Susan Potter Thinking in Properties 2020-08-01 25 / 41
Mental Models
Deriving Properties: Relational laws
-- implicitly expect sort and last to be correct
prop_max_is_last_of_sort = property $ do
xs <- forAll $ genList Gen.ascii
Just (max xs) === last (sort xs)
prop_last_is_first_of_reversed = property $ do
xs <- forAll $ genList Gen.unicode
last xs === first (reverse xs)
Susan Potter Thinking in Properties 2020-08-01 26 / 41
Mental Models
Deriving Properties: Abstraction laws
Using hedgehog-classes package we can check our typeclass instances
according to the abstraction laws:
import Hedgehog
import Hedgehog.Classes
import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
investmentPortfolioSemigroup
= lawsCheck (semigroupLaws genInvestmentPortfolio)
portfolioFoldable = lawsCheck (foldableLaws genPortfolio)
Susan Potter Thinking in Properties 2020-08-01 27 / 41
Mental Models
Deriving Properties: Reflections, Rotations, Distortions
prop_rotated_colors_same
= property $ do
img <- forAll $ genImage
colors (rotate90 img) === colors img
• normalizing audio shouldn’t change time length
• reversing a list shouldn’t change length
Susan Potter Thinking in Properties 2020-08-01 28 / 41
Mental Models
Deriving Properties: Informal model checking
Sometimes you can model the basic state machine of a system simply:
• model of interesting parts of stateful system
• not exhaustive
• thinking in state machine models
• generate sequence or call graph of commands
• assert pre- and post-conditions or invariants
• careful you don’t write a second implementation of the SUT just to test it!
Susan Potter Thinking in Properties 2020-08-01 29 / 41
Mental Models
Deriving Properties: Legacy oracles
Replacing legacy systems:
• bind to old lib as oracle
• assert new rewritten library matches oracle for same inputs
• good for e.g. calculation engines or data pipelines
• might need large build engineering effort
Susan Potter Thinking in Properties 2020-08-01 30 / 41
Mental Models
Deriving Properties: Does not barf
Wrapping lower-level code via FFI:
• gaps between foreign input or output types and native types
• runtime exceptions thrown for some input values (inform design)
• sanity checking FFI wrapping
Susan Potter Thinking in Properties 2020-08-01 31 / 41
Mental Models
Deriving Properties: Metamorphic relations
• Running against SUT twice with possibly different inputs
• A relation exists between those inputs
• Assert a relation exists between the outputs of those system runs
An example across inputs and outputs, but the relation between inputs and
outputs can be different: x, y ∈ Inputs, x ≤ y, x′
= SUT(x), y′
= SUT(y) then
x′
≤ y′
Susan Potter Thinking in Properties 2020-08-01 32 / 41
Mental Models
Deriving Properties: Metamorphic relation patterns
• Input equivalence
• Shuffling
• Conjunctive conditions
• Disjunctive conditions
• Disjoint partitions
• Complete partitions
• Partition difference
Susan Potter Thinking in Properties 2020-08-01 33 / 41
Mental Models
Deriving Properties: Heckle Yourself!
• mutation testing
• alter your code until your tests fail
• if no tests fail, throw your tests out
(curation)
• question your assumptions
Susan Potter Thinking in Properties 2020-08-01 34 / 41
Beyond testing
Beyond testing
Properties of Delivery Pipelines
Property: Source consistency Ensuring fast-forward only ”merges”:
main() {
local -r mergeBase="$(git merge-base HEAD origin/deploy)"
local -r deployHead="$(git rev-parse origin/deploy)"
test "${mergeBase}" = "${deployHead}"
}
set -e
main
# should exit with 0 for success
Susan Potter Thinking in Properties 2020-08-01 35 / 41
Beyond testing
Stateful Migrations (in production)
Properties: pre and post conditions and invariants between migration phases
• moving a stateful cluster from one datacenter to another
• upgrading Elastic search into a new cluster
• online schema migrations of large tables with binlog syncing and atomic
rename (e.g. MySQL)
Susan Potter Thinking in Properties 2020-08-01 36 / 41
Beyond testing
Stateful Migrations (in production)
Properties: pre and post conditions and invariants between migration phases
• moving a stateful cluster from one datacenter to another
• upgrading Elastic search into a new cluster
• online schema migrations of large tables with binlog syncing and atomic
rename (e.g. MySQL)
Susan Potter Thinking in Properties 2020-08-01 36 / 41
Beyond testing
Stateful Migrations (in production)
Properties: pre and post conditions and invariants between migration phases
• moving a stateful cluster from one datacenter to another
• upgrading Elastic search into a new cluster
• online schema migrations of large tables with binlog syncing and atomic
rename (e.g. MySQL)
Susan Potter Thinking in Properties 2020-08-01 36 / 41
Beyond testing
System Monitoring
Property: Connectedness!
Given public name for service name:
• resolve name to A records (IPs)
• ∀ IPs should negotiate TLS handshake
• ∀ IPs should make HTTP request with Host
Susan Potter Thinking in Properties 2020-08-01 37 / 41
Beyond testing
System Monitoring
Property: Connectedness!
Given public name for service name:
• resolve name to A records (IPs)
• ∀ IPs should negotiate TLS handshake
• ∀ IPs should make HTTP request with Host
Susan Potter Thinking in Properties 2020-08-01 37 / 41
Beyond testing
System Monitoring
Property: Connectedness!
Given public name for service name:
• resolve name to A records (IPs)
• ∀ IPs should negotiate TLS handshake
• ∀ IPs should make HTTP request with Host
Susan Potter Thinking in Properties 2020-08-01 37 / 41
Beyond testing
Production Data Checks
Sometimes your generators don’t generate data you see in production!
Legacy systems exist with no property-based testing toolchain!
• Structured logging can record inputs and results; validate OOB
• Run property checks against production inputs and outputs in Haskell :)
Susan Potter Thinking in Properties 2020-08-01 38 / 41
Wrapping Up
Wrapping Up
In Closing
• Not all properties are useful
• Initially hard to think up useful properties
genMentalModels = Gen.choice [
genAlgebraicLaws, genRelationalLaws,
genAbstrationLaws, genStateMachines,
genMetamorphicRelations,
genHeckleYourCode,
genTestingInProduction
]
Susan Potter Thinking in Properties 2020-08-01 39 / 41
Wrapping Up
In Closing
• Not all properties are useful
• Initially hard to think up useful properties
genMentalModels = Gen.choice [
genAlgebraicLaws, genRelationalLaws,
genAbstrationLaws, genStateMachines,
genMetamorphicRelations,
genHeckleYourCode,
genTestingInProduction
]
Susan Potter Thinking in Properties 2020-08-01 39 / 41
Wrapping Up
Questions?
GitHub @mbbx6spp
LinkedIn /in/susanpotter
Twitter @SusanPotter
Web Personal site
Consulting
Training
Thank you for listening!
Susan Potter Thinking in Properties 2020-08-01 40 / 41
Wrapping Up
Credits
• Photo by Elias Castillo on Unsplash
• Photo by Juan Rumimpunu on Unsplash
• Photo by LinkedIn Sales Navigator on Unsplash
• Photo by Leonardo Sanches on Unsplash
• Photo by Mélissa Jeanty on Unsplash
• Photo by Chris Liverani on Unsplash
• Photo by <a href=”https:
//unsplash.com/@spanic?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText”>Damir Spanic</a>
on <a href=”https://unsplash.com/s/photos/baseball-bat?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=
creditCopyText”>Unsplash</a></span>
• Photo by <a href=”https:
//unsplash.com/@serrah?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText”>Serrah Galos</a>
on <a href=”https://unsplash.com/s/photos/reflection?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=
creditCopyText”>Unsplash</a></span>
• Photo by Sergey Zolkin on Unsplash
• Photo by Roman Mager on Unsplash
• Photo by Miguel Ibáñez on Unsplash
• Photo by Science in HD on Unsplash
• Photo by Steve Douglas on Unsplash
• Photo by Natalie Parham on Unsplash
Susan Potter Thinking in Properties 2020-08-01 41 / 41
1 of 68

Recommended

Oleksandr Valetskyy - Increase the quality of your code with property-based t... by
Oleksandr Valetskyy - Increase the quality of your code with property-based t...Oleksandr Valetskyy - Increase the quality of your code with property-based t...
Oleksandr Valetskyy - Increase the quality of your code with property-based t...Oleksandr Valetskyy
279 views54 slides
Google guava overview by
Google guava overviewGoogle guava overview
Google guava overviewSteve Min
6.9K views127 slides
Clean code with google guava jee conf by
Clean code with google guava jee confClean code with google guava jee conf
Clean code with google guava jee confIgor Anishchenko
10.5K views113 slides
Measuring the IQ of your Threat Intelligence Feeds (#tiqtest) by
Measuring the IQ of your Threat Intelligence Feeds (#tiqtest)Measuring the IQ of your Threat Intelligence Feeds (#tiqtest)
Measuring the IQ of your Threat Intelligence Feeds (#tiqtest)Alex Pinto
12.1K views42 slides
07-Classification.pptx by
07-Classification.pptx07-Classification.pptx
07-Classification.pptxShree Shree
5 views52 slides
Fact based monitoring by
Fact based monitoringFact based monitoring
Fact based monitoringDatadog
314 views35 slides

More Related Content

Similar to Thinking in Properties

Empirical Evaluations in Software Engineering Research: A Personal Perspective by
Empirical Evaluations in Software Engineering Research: A Personal PerspectiveEmpirical Evaluations in Software Engineering Research: A Personal Perspective
Empirical Evaluations in Software Engineering Research: A Personal PerspectiveSAIL_QU
880 views112 slides
Goss_ICCVE 2022.pdf by
Goss_ICCVE 2022.pdfGoss_ICCVE 2022.pdf
Goss_ICCVE 2022.pdfM. Ilhan Akbas
12 views31 slides
ScalaCheck by
ScalaCheckScalaCheck
ScalaCheckBeScala
2.5K views18 slides
Splunk bsides by
Splunk bsidesSplunk bsides
Splunk bsidesMacy Cronkrite
1.5K views25 slides
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu... by
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...Daniel Bohannon
3.4K views129 slides
Jquery2012 defs by
Jquery2012 defsJquery2012 defs
Jquery2012 defs司徒 正美
435 views135 slides

Similar to Thinking in Properties(20)

Empirical Evaluations in Software Engineering Research: A Personal Perspective by SAIL_QU
Empirical Evaluations in Software Engineering Research: A Personal PerspectiveEmpirical Evaluations in Software Engineering Research: A Personal Perspective
Empirical Evaluations in Software Engineering Research: A Personal Perspective
SAIL_QU880 views
ScalaCheck by BeScala
ScalaCheckScalaCheck
ScalaCheck
BeScala2.5K views
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu... by Daniel Bohannon
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...
Invoke-CradleCrafter: Moar PowerShell obFUsk8tion & Detection (@('Tech','niqu...
Daniel Bohannon3.4K views
Lessons Learnt From Working With Rails by martinbtt
Lessons Learnt From Working With RailsLessons Learnt From Working With Rails
Lessons Learnt From Working With Rails
martinbtt496 views
Relatedness-based Multi-Entity Summarization by Gong Cheng
Relatedness-based Multi-Entity SummarizationRelatedness-based Multi-Entity Summarization
Relatedness-based Multi-Entity Summarization
Gong Cheng449 views
Testing Variability-Intensive Systems, tutorial SPLC 2017, part I by XavierDevroey
Testing Variability-Intensive Systems, tutorial SPLC 2017, part ITesting Variability-Intensive Systems, tutorial SPLC 2017, part I
Testing Variability-Intensive Systems, tutorial SPLC 2017, part I
XavierDevroey99 views
Clean Manifests with Puppet::Tidy by Puppet
Clean Manifests with Puppet::TidyClean Manifests with Puppet::Tidy
Clean Manifests with Puppet::Tidy
Puppet4.5K views
SplunkLive! Customer Presentation - Cisco Systems, Inc. by Splunk
SplunkLive! Customer Presentation - Cisco Systems, Inc.SplunkLive! Customer Presentation - Cisco Systems, Inc.
SplunkLive! Customer Presentation - Cisco Systems, Inc.
Splunk2.1K views
Refactoring RIA Unleashed 2011 by Jesse Warden
Refactoring RIA Unleashed 2011Refactoring RIA Unleashed 2011
Refactoring RIA Unleashed 2011
Jesse Warden767 views
Splunk Live in RTP - March-2014-Jeff-Bollinger-Cisco by Jeff Bollinger
Splunk Live in RTP - March-2014-Jeff-Bollinger-CiscoSplunk Live in RTP - March-2014-Jeff-Bollinger-Cisco
Splunk Live in RTP - March-2014-Jeff-Bollinger-Cisco
Jeff Bollinger706 views
Apache Kylin - Balance Between Space and Time by DataWorks Summit
Apache Kylin - Balance Between Space and TimeApache Kylin - Balance Between Space and Time
Apache Kylin - Balance Between Space and Time
DataWorks Summit2.5K views
Puppet Roles & Profiles Using Trusted Facts. by Stephen Wallace
Puppet Roles & Profiles Using Trusted Facts.Puppet Roles & Profiles Using Trusted Facts.
Puppet Roles & Profiles Using Trusted Facts.
Stephen Wallace2.1K views
Perf onjs final by qi yang
Perf onjs finalPerf onjs final
Perf onjs final
qi yang302 views

More from Susan Potter

Champaign-Urbana Javascript Meetup Talk (Jan 2020) by
Champaign-Urbana Javascript Meetup Talk (Jan 2020)Champaign-Urbana Javascript Meetup Talk (Jan 2020)
Champaign-Urbana Javascript Meetup Talk (Jan 2020)Susan Potter
151 views40 slides
From Zero to Haskell: Lessons Learned by
From Zero to Haskell: Lessons LearnedFrom Zero to Haskell: Lessons Learned
From Zero to Haskell: Lessons LearnedSusan Potter
136 views76 slides
Dynamically scaling a political news and activism hub (up to 5x the traffic i... by
Dynamically scaling a political news and activism hub (up to 5x the traffic i...Dynamically scaling a political news and activism hub (up to 5x the traffic i...
Dynamically scaling a political news and activism hub (up to 5x the traffic i...Susan Potter
103 views69 slides
Functional Operations (Functional Programming at Comcast Labs Connect) by
Functional Operations (Functional Programming at Comcast Labs Connect)Functional Operations (Functional Programming at Comcast Labs Connect)
Functional Operations (Functional Programming at Comcast Labs Connect)Susan Potter
385 views40 slides
From Zero to Application Delivery with NixOS by
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOSSusan Potter
2.9K views71 slides
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016 by
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016Susan Potter
2.5K views64 slides

More from Susan Potter(17)

Champaign-Urbana Javascript Meetup Talk (Jan 2020) by Susan Potter
Champaign-Urbana Javascript Meetup Talk (Jan 2020)Champaign-Urbana Javascript Meetup Talk (Jan 2020)
Champaign-Urbana Javascript Meetup Talk (Jan 2020)
Susan Potter151 views
From Zero to Haskell: Lessons Learned by Susan Potter
From Zero to Haskell: Lessons LearnedFrom Zero to Haskell: Lessons Learned
From Zero to Haskell: Lessons Learned
Susan Potter136 views
Dynamically scaling a political news and activism hub (up to 5x the traffic i... by Susan Potter
Dynamically scaling a political news and activism hub (up to 5x the traffic i...Dynamically scaling a political news and activism hub (up to 5x the traffic i...
Dynamically scaling a political news and activism hub (up to 5x the traffic i...
Susan Potter103 views
Functional Operations (Functional Programming at Comcast Labs Connect) by Susan Potter
Functional Operations (Functional Programming at Comcast Labs Connect)Functional Operations (Functional Programming at Comcast Labs Connect)
Functional Operations (Functional Programming at Comcast Labs Connect)
Susan Potter385 views
From Zero to Application Delivery with NixOS by Susan Potter
From Zero to Application Delivery with NixOSFrom Zero to Application Delivery with NixOS
From Zero to Application Delivery with NixOS
Susan Potter2.9K views
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016 by Susan Potter
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
From Zero To Production (NixOS, Erlang) @ Erlang Factory SF 2016
Susan Potter2.5K views
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014 by Susan Potter
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Susan Potter2.9K views
Ricon/West 2013: Adventures with Riak Pipe by Susan Potter
Ricon/West 2013: Adventures with Riak PipeRicon/West 2013: Adventures with Riak Pipe
Ricon/West 2013: Adventures with Riak Pipe
Susan Potter1.9K views
Functional Algebra: Monoids Applied by Susan Potter
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
Susan Potter4.1K views
Dynamo: Not Just For Datastores by Susan Potter
Dynamo: Not Just For DatastoresDynamo: Not Just For Datastores
Dynamo: Not Just For Datastores
Susan Potter1.7K views
Distributed Developer Workflows using Git by Susan Potter
Distributed Developer Workflows using GitDistributed Developer Workflows using Git
Distributed Developer Workflows using Git
Susan Potter2K views
Link Walking with Riak by Susan Potter
Link Walking with RiakLink Walking with Riak
Link Walking with Riak
Susan Potter2.7K views
Writing Bullet-Proof Javascript: By Using CoffeeScript by Susan Potter
Writing Bullet-Proof Javascript: By Using CoffeeScriptWriting Bullet-Proof Javascript: By Using CoffeeScript
Writing Bullet-Proof Javascript: By Using CoffeeScript
Susan Potter1.5K views
Deploying distributed software services to the cloud without breaking a sweat by Susan Potter
Deploying distributed software services to the cloud without breaking a sweatDeploying distributed software services to the cloud without breaking a sweat
Deploying distributed software services to the cloud without breaking a sweat
Susan Potter1.1K views
Designing for Concurrency by Susan Potter
Designing for ConcurrencyDesigning for Concurrency
Designing for Concurrency
Susan Potter959 views

Recently uploaded

BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports by
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsBushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsRa'Fat Al-Msie'deen
8 views49 slides
SAP FOR CONTRACT MANUFACTURING.pdf by
SAP FOR CONTRACT MANUFACTURING.pdfSAP FOR CONTRACT MANUFACTURING.pdf
SAP FOR CONTRACT MANUFACTURING.pdfVirendra Rai, PMP
13 views2 slides
Quality Engineer: A Day in the Life by
Quality Engineer: A Day in the LifeQuality Engineer: A Day in the Life
Quality Engineer: A Day in the LifeJohn Valentino
6 views18 slides
Introduction to Git Source Control by
Introduction to Git Source ControlIntroduction to Git Source Control
Introduction to Git Source ControlJohn Valentino
5 views18 slides
SAP FOR TYRE INDUSTRY.pdf by
SAP FOR TYRE INDUSTRY.pdfSAP FOR TYRE INDUSTRY.pdf
SAP FOR TYRE INDUSTRY.pdfVirendra Rai, PMP
24 views3 slides
The Path to DevOps by
The Path to DevOpsThe Path to DevOps
The Path to DevOpsJohn Valentino
5 views6 slides

Recently uploaded(20)

BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports by Ra'Fat Al-Msie'deen
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug ReportsBushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
BushraDBR: An Automatic Approach to Retrieving Duplicate Bug Reports
Quality Engineer: A Day in the Life by John Valentino
Quality Engineer: A Day in the LifeQuality Engineer: A Day in the Life
Quality Engineer: A Day in the Life
John Valentino6 views
Introduction to Git Source Control by John Valentino
Introduction to Git Source ControlIntroduction to Git Source Control
Introduction to Git Source Control
John Valentino5 views
Ports-and-Adapters Architecture for Embedded HMI by Burkhard Stubert
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMI
Burkhard Stubert21 views
FIMA 2023 Neo4j & FS - Entity Resolution.pptx by Neo4j
FIMA 2023 Neo4j & FS - Entity Resolution.pptxFIMA 2023 Neo4j & FS - Entity Resolution.pptx
FIMA 2023 Neo4j & FS - Entity Resolution.pptx
Neo4j8 views
Dapr Unleashed: Accelerating Microservice Development by Miroslav Janeski
Dapr Unleashed: Accelerating Microservice DevelopmentDapr Unleashed: Accelerating Microservice Development
Dapr Unleashed: Accelerating Microservice Development
Miroslav Janeski10 views
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with... by sparkfabrik
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
sparkfabrik7 views
Top-5-production-devconMunich-2023.pptx by Tier1 app
Top-5-production-devconMunich-2023.pptxTop-5-production-devconMunich-2023.pptx
Top-5-production-devconMunich-2023.pptx
Tier1 app7 views
predicting-m3-devopsconMunich-2023.pptx by Tier1 app
predicting-m3-devopsconMunich-2023.pptxpredicting-m3-devopsconMunich-2023.pptx
predicting-m3-devopsconMunich-2023.pptx
Tier1 app7 views
Navigating container technology for enhanced security by Niklas Saari by Metosin Oy
Navigating container technology for enhanced security by Niklas SaariNavigating container technology for enhanced security by Niklas Saari
Navigating container technology for enhanced security by Niklas Saari
Metosin Oy14 views
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated... by TomHalpin9
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
Dev-HRE-Ops - Addressing the _Last Mile DevOps Challenge_ in Highly Regulated...
TomHalpin96 views
Gen Apps on Google Cloud PaLM2 and Codey APIs in Action by Márton Kodok
Gen Apps on Google Cloud PaLM2 and Codey APIs in ActionGen Apps on Google Cloud PaLM2 and Codey APIs in Action
Gen Apps on Google Cloud PaLM2 and Codey APIs in Action
Márton Kodok6 views

Thinking in Properties

  • 1. Thinking in Properties And Beyond (Testing) Susan Potter 2020-08-01
  • 3. Intro finger $(whoami) • Introduced to QuickCheck in Erlang ~2010 • Adopted Haskell’s QuickCheck, Hedgehog, and ScalaCheck at work • ”Testing” in production, thinking in properties, 4 years Susan Potter Thinking in Properties 2020-08-01 1 / 41
  • 4. Intro Agenda • An Origin Story (with code) • Mental Models (above the code) • Beyond Testing (illustrations) Susan Potter Thinking in Properties 2020-08-01 2 / 41
  • 6. An Origin Story Discovering Superpowers Susan Potter Thinking in Properties 2020-08-01 3 / 41
  • 7. An Origin Story Discovering Superpowers Explore domain with types data List a = EmptyList | Cons a (List a) type Pred a = (a -> Bool) type Comp a = (a -> a -> Ordering) sortBy :: Comp a -> List a -> List a filter :: Pred a -> List a -> List a reverse :: List a -> List a last, first :: List a -> Maybe a Susan Potter Thinking in Properties 2020-08-01 3 / 41
  • 8. An Origin Story Discovering Superpowers Explore domain with usage examples -- | Reverse the elements of a list -- >>> reverse (Cons 1 (Cons 2 (Cons 3 EmptyList)))→ -- Cons 3 (Cons 2 (Cons 1 EmptyList)) -- -- >>> reverse EmptyList -- EmptyList reverse :: List a -> List a Susan Potter Thinking in Properties 2020-08-01 4 / 41
  • 9. An Origin Story Discovering Superpowers Encode examples as re-runnable tests describe "Lib.reverse" $ do it "returns [5,4,3,2,1] given [1,2,3,4,5]" $ do reverse [1,2,3,4,5] `shouldBe` [5,4,3,2,1] it "returns empty list given empty list" $ do reverse [] `shouldBe` [] Susan Potter Thinking in Properties 2020-08-01 5 / 41
  • 10. An Origin Story Discovering Superpowers Rinse & Repeat Susan Potter Thinking in Properties 2020-08-01 6 / 41
  • 11. An Origin Story Discovering Superpowers Continuous Learning Figure 1: Schedule for Erlang Factory SF 2011 where my mind was blown Susan Potter Thinking in Properties 2020-08-01 7 / 41
  • 12. An Origin Story Harnessing Newly Found Superpowers Characteristics of property-based testing Where we have: • generators that produce random ”arbitrary” values for inputs • general rules that hold without knowing inputs upfront • shrinking of failed values • test runs assert rule multiple times using new generated values Related terms: generative testing, fuzz testing (or ”fuzzing”) Susan Potter Thinking in Properties 2020-08-01 8 / 41
  • 13. An Origin Story Harnessing Newly Found Superpowers Characteristics of property-based testing Where we have: • generators that produce random ”arbitrary” values for inputs • general rules that hold without knowing inputs upfront • shrinking of failed values • test runs assert rule multiple times using new generated values Related terms: generative testing, fuzz testing (or ”fuzzing”) Susan Potter Thinking in Properties 2020-08-01 8 / 41
  • 14. An Origin Story Harnessing Newly Found Superpowers Characteristics of property-based testing Where we have: • generators that produce random ”arbitrary” values for inputs • general rules that hold without knowing inputs upfront • shrinking of failed values • test runs assert rule multiple times using new generated values Related terms: generative testing, fuzz testing (or ”fuzzing”) Susan Potter Thinking in Properties 2020-08-01 8 / 41
  • 15. An Origin Story Harnessing Newly Found Superpowers Characteristics of property-based testing Where we have: • generators that produce random ”arbitrary” values for inputs • general rules that hold without knowing inputs upfront • shrinking of failed values • test runs assert rule multiple times using new generated values Related terms: generative testing, fuzz testing (or ”fuzzing”) Susan Potter Thinking in Properties 2020-08-01 8 / 41
  • 16. An Origin Story Harnessing Newly Found Superpowers One General Rule: Round-tripping (two rides gets us back home) Examples: -- Assumes x is encodable and decodable roundtrip0 = x -> decode (encode x) == Just x roundtrip1 = x -> decodeBase64 (encodeBase64 x) == Right x Counter-examples: • sha256 is one way! Susan Potter Thinking in Properties 2020-08-01 9 / 41
  • 17. An Origin Story Harnessing Newly Found Superpowers Introducing generators To make these ideas concrete we will be using hedgehog with these imports: import Hedgehog import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import Control.Monad (replicateM) import Data.Function (($), (.)) Hedgehog integrates shrinking with generation. We will not discuss this difference to QuickCheck but read Well Typed’s blog post about this here. Susan Potter Thinking in Properties 2020-08-01 10 / 41
  • 18. An Origin Story Harnessing Newly Found Superpowers Primitive generators by example >>> replicateM 25 $ Gen.sample Gen.lower "okohcpxrkfunkmwnqujnnhxkg" >>> let currencies = [ "USD", "JPY", "EUR", "CHF", "CNY" ] >>> replicateM 5 $ Gen.sample $ Gen.element currencies ["USD","CNY","USD","JPY","USD"] >>> replicateM 5 $ Gen.sample $ Gen.choice [ Gen.ascii, Gen.unicode ]→ ['f', 'c', 'j', '1068213', '<'] Susan Potter Thinking in Properties 2020-08-01 11 / 41
  • 19. An Origin Story Harnessing Newly Found Superpowers Generating your domain’s data, 1/2 Suppose our domain looks like this: import Data.Word (Word8, Word16) type W16 = Word16 data IP = IPv4 Word8 Word8 Word8 Word8 | IPv6 W16 W16 W16 W16 W16 W16 W16 W16 Susan Potter Thinking in Properties 2020-08-01 12 / 41
  • 20. An Origin Story Harnessing Newly Found Superpowers Generating your domain’s data, 2/2 genW8 = Gen.word8 Range.constantBounded genW16 = Gen.word16 Range.constantBounded genIPv4 = IPv4 <$> genW8 <*> genW8 <*> genW8 <*> genW8 genIPv6 = IPv6 <$> genW16 <*> genW16 <*> genW16 <*> genW16 <*> genW16 <*> genW16 <*> genW16 <*> genW16 genAnyIP = Gen.choice [ genIPv4, genIPv6 ] sampleIPs n = replicateM n (Gen.sample genAnyIP) Susan Potter Thinking in Properties 2020-08-01 13 / 41
  • 21. An Origin Story Harnessing Newly Found Superpowers Sampling generated domain data >>> sampleIPs 3 [ "136.59.149.200" , "338d:2397:f612:e036:b27c:2298:4db8:b933" , "5.38.65.204" ] Susan Potter Thinking in Properties 2020-08-01 14 / 41
  • 22. An Origin Story Harnessing Newly Found Superpowers Writing Our First Property! genList :: MonadGen m => m a -> m [a] genList = Gen.list (Range.linear 0 1000) genInt = Gen.int (Range.linear 0 100000) -- "round-tripping" property prop_reverse_reverse = property $ do xs <- forAll $ genList genInt Lib.reverse (Lib.reverse xs) === xs Susan Potter Thinking in Properties 2020-08-01 15 / 41
  • 23. An Origin Story Harnessing Newly Found Superpowers Reviewing Our First Property! Questions about prop_reverse_reverse: • Does it assert anything about reverse ’s specification? • Do callers of reverse need to exploit ”round-tripping”? • Does an implementation exist that typechecks yet fails this property? • Are we generating interesting data given the operation’s type? • Are we resigned to function-level property testing? Susan Potter Thinking in Properties 2020-08-01 16 / 41
  • 24. An Origin Story Harnessing Newly Found Superpowers Reviewing Our First Property! Questions about prop_reverse_reverse: • Does it assert anything about reverse ’s specification? • Do callers of reverse need to exploit ”round-tripping”? • Does an implementation exist that typechecks yet fails this property? • Are we generating interesting data given the operation’s type? • Are we resigned to function-level property testing? Susan Potter Thinking in Properties 2020-08-01 16 / 41
  • 25. An Origin Story Harnessing Newly Found Superpowers Reviewing Our First Property! Questions about prop_reverse_reverse: • Does it assert anything about reverse ’s specification? • Do callers of reverse need to exploit ”round-tripping”? • Does an implementation exist that typechecks yet fails this property? • Are we generating interesting data given the operation’s type? • Are we resigned to function-level property testing? Susan Potter Thinking in Properties 2020-08-01 16 / 41
  • 26. An Origin Story Harnessing Newly Found Superpowers Reviewing Our First Property! Questions about prop_reverse_reverse: • Does it assert anything about reverse ’s specification? • Do callers of reverse need to exploit ”round-tripping”? • Does an implementation exist that typechecks yet fails this property? • Are we generating interesting data given the operation’s type? • Are we resigned to function-level property testing? Susan Potter Thinking in Properties 2020-08-01 16 / 41
  • 27. An Origin Story Harnessing Newly Found Superpowers Reviewing Our First Property! Questions about prop_reverse_reverse: • Does it assert anything about reverse ’s specification? • Do callers of reverse need to exploit ”round-tripping”? • Does an implementation exist that typechecks yet fails this property? • Are we generating interesting data given the operation’s type? • Are we resigned to function-level property testing? Susan Potter Thinking in Properties 2020-08-01 16 / 41
  • 28. An Origin Story Harnessing Newly Found Superpowers Quick Review: Example-based tests over time t ~ 0 → t → ∞ Quick ⌣ →  / ⌢ Coverage ? →  / ⌢ Repeatable ⌣ →  / ⌢ Documents usage  →  / ⌢ Documents contract ⌢ → ⌢ Effort  →  / ⌢ • can measure coverage • fixtures provide test data • interesting fixtures brittle • over time tends to ⌢ Susan Potter Thinking in Properties 2020-08-01 17 / 41
  • 29. An Origin Story Harnessing Newly Found Superpowers Quick Review: Example-based tests over time t ~ 0 → t → ∞ Quick ⌣ →  / ⌢ Coverage ? →  / ⌢ Repeatable ⌣ →  / ⌢ Documents usage  →  / ⌢ Documents contract ⌢ → ⌢ Effort  →  / ⌢ • can measure coverage • fixtures provide test data • interesting fixtures brittle • over time tends to ⌢ Susan Potter Thinking in Properties 2020-08-01 17 / 41
  • 30. An Origin Story Harnessing Newly Found Superpowers Quick Review: Example-based tests over time t ~ 0 → t → ∞ Quick ⌣ →  / ⌢ Coverage ? →  / ⌢ Repeatable ⌣ →  / ⌢ Documents usage  →  / ⌢ Documents contract ⌢ → ⌢ Effort  →  / ⌢ • can measure coverage • fixtures provide test data • interesting fixtures brittle • over time tends to ⌢ Susan Potter Thinking in Properties 2020-08-01 17 / 41
  • 31. An Origin Story Harnessing Newly Found Superpowers Quick Review: Example-based tests over time t ~ 0 → t → ∞ Quick ⌣ →  / ⌢ Coverage ? →  / ⌢ Repeatable ⌣ →  / ⌢ Documents usage  →  / ⌢ Documents contract ⌢ → ⌢ Effort  →  / ⌢ • can measure coverage • fixtures provide test data • interesting fixtures brittle • over time tends to ⌢ Susan Potter Thinking in Properties 2020-08-01 17 / 41
  • 32. An Origin Story Harnessing Newly Found Superpowers Quick Review: Example-based tests over time t ~ 0 → t → ∞ Quick ⌣ →  / ⌢ Coverage ? →  / ⌢ Repeatable ⌣ →  / ⌢ Documents usage  →  / ⌢ Documents contract ⌢ → ⌢ Effort  →  / ⌢ • can measure coverage • fixtures provide test data • interesting fixtures brittle • over time tends to ⌢ Susan Potter Thinking in Properties 2020-08-01 17 / 41
  • 33. An Origin Story Harnessing Newly Found Superpowers Quick Review: Property-based tests initially t ~ 0 Quick ⌣ Coverage ⌣ Repeatable ⌣ Documents usage  Documents contract ⌣ /  Effort ? • Can we measure coverage ? • We need to maintain generators instead of fixtures! • Not constrained by imagination! ⌣ • Am I smart enough to think up relevant and meaningful properties ? Susan Potter Thinking in Properties 2020-08-01 18 / 41
  • 34. An Origin Story Harnessing Newly Found Superpowers Quick Review: Property-based tests initially t ~ 0 Quick ⌣ Coverage ⌣ Repeatable ⌣ Documents usage  Documents contract ⌣ /  Effort ? • Can we measure coverage ? • We need to maintain generators instead of fixtures! • Not constrained by imagination! ⌣ • Am I smart enough to think up relevant and meaningful properties ? Susan Potter Thinking in Properties 2020-08-01 18 / 41
  • 35. An Origin Story Harnessing Newly Found Superpowers Quick Review: Property-based tests initially t ~ 0 Quick ⌣ Coverage ⌣ Repeatable ⌣ Documents usage  Documents contract ⌣ /  Effort ? • Can we measure coverage ? • We need to maintain generators instead of fixtures! • Not constrained by imagination! ⌣ • Am I smart enough to think up relevant and meaningful properties ? Susan Potter Thinking in Properties 2020-08-01 18 / 41
  • 36. An Origin Story Harnessing Newly Found Superpowers Quick Review: Property-based tests initially t ~ 0 Quick ⌣ Coverage ⌣ Repeatable ⌣ Documents usage  Documents contract ⌣ /  Effort ? • Can we measure coverage ? • We need to maintain generators instead of fixtures! • Not constrained by imagination! ⌣ • Am I smart enough to think up relevant and meaningful properties ? Susan Potter Thinking in Properties 2020-08-01 18 / 41
  • 37. An Origin Story Harnessing Newly Found Superpowers Quick Review: Property-based tests initially t ~ 0 Quick ⌣ Coverage ⌣ Repeatable ⌣ Documents usage  Documents contract ⌣ /  Effort ? • Can we measure coverage ? • We need to maintain generators instead of fixtures! • Not constrained by imagination! ⌣ • Am I smart enough to think up relevant and meaningful properties ? Susan Potter Thinking in Properties 2020-08-01 18 / 41
  • 39. Mental Models Deriving Properties: Algebraic laws Law What might it be good for Idempotency e.g. event log effects, REST APIs, config effects Associativity e.g. map/reduce distribution Commutativity e.g. map/reduce local parallelism Distributivity e.g. stable or performant rewrite rules Identity element e.g. for invariance at that value for operation Round-tripping e.g. encoding/decoding Absorption e.g. boolean algebra rewrites Transitivity e.g. dependency closures Susan Potter Thinking in Properties 2020-08-01 19 / 41
  • 40. Mental Models Algebraic laws: Idempotency (running 1+ times yields same result) Examples: idem0 = x -> abs x == abs (abs x) idem2 = x -> toUpper s == toUpper (toUpper s) • curl -XPUT https://foo.bar/resource/123 -d baz=qux Counter-example: • curl -XPOST https://foo.bar/resource -d baz=qux Algebra: Given x ∈ A and f ∈ (A → A) and f(x) = f(f(x)) then f is idempotent. Susan Potter Thinking in Properties 2020-08-01 20 / 41
  • 41. Mental Models Algebraic laws: Associativity (brackets to the left or right) Examples: assoc0 = x y z -> (x + y) + z == x + (y + z) assoc1 = x y z -> (x ++ y) ++ z == x ++ (y ++ z) Counter-example: • (x − y) − z = x − (y − z) Algebra: Given x, y, z ∈ A, ⊕ ∈ (A → A → A) and (x ⊕ y) ⊕ z = x ⊕ (y ⊕ z) then ⊕ is associative. Susan Potter Thinking in Properties 2020-08-01 21 / 41
  • 42. Mental Models Algebraic laws: Commutativity (any order will do) Examples: comm0 = x y -> x + y == y + x comm1 = x y -> x * y == y * x Counter-example: • x + +y = y + +x • x − y = y − x Algebra: Given x, y ∈ A, ⊕ ∈ (A → A → A) and $x ⊕ y = y ⊕x then ⊕ is commutative. Susan Potter Thinking in Properties 2020-08-01 22 / 41
  • 43. Mental Models Algebraic laws: Distributivity (one operation over another) Examples: dist0 = x y z -> x*(y + z) == x*y + x*z Counter-example: • x + (y ∗ z) = x + y ∗ x + z where x = 1, y = 2, z = 3 1 + (2 ∗ 3) = 1 + 2 ∗ 1 + 3 ⇒ 7 = 6 Algebra: Given x, y, z ∈ A and ⊕, ⊗ ∈ (A → A → A) then ⊗ is distributive over ⊕ when x ⊗ (y ⊕ z) = x ⊗ y ⊕ x ⊗ z Susan Potter Thinking in Properties 2020-08-01 23 / 41
  • 44. Mental Models Algebraic laws: Identity element Examples: identity0 = x -> 0 + x == x identity1 = x -> False || x == x identity2 = s -> "" ++ s == s Counter-example: -NonEmpty does not have an identity element Algebra: ∃e ∈ A, ∀a ∈ A, e ⊕ a = a then e is the identity element in A. Susan Potter Thinking in Properties 2020-08-01 24 / 41
  • 45. Mental Models Algebraic laws: Absorption Examples: absorption0 = a b -> (a || (a && b)) == a absorption1 = a b -> (a && (a || b)) == a Algebra: Given ∧, ∨ ∈ (A → A → A) and a, b ∈ A then when a ∧ (a ∨ b) = a = a ∨ (a ∧ b) Susan Potter Thinking in Properties 2020-08-01 25 / 41
  • 46. Mental Models Deriving Properties: Relational laws -- implicitly expect sort and last to be correct prop_max_is_last_of_sort = property $ do xs <- forAll $ genList Gen.ascii Just (max xs) === last (sort xs) prop_last_is_first_of_reversed = property $ do xs <- forAll $ genList Gen.unicode last xs === first (reverse xs) Susan Potter Thinking in Properties 2020-08-01 26 / 41
  • 47. Mental Models Deriving Properties: Abstraction laws Using hedgehog-classes package we can check our typeclass instances according to the abstraction laws: import Hedgehog import Hedgehog.Classes import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range investmentPortfolioSemigroup = lawsCheck (semigroupLaws genInvestmentPortfolio) portfolioFoldable = lawsCheck (foldableLaws genPortfolio) Susan Potter Thinking in Properties 2020-08-01 27 / 41
  • 48. Mental Models Deriving Properties: Reflections, Rotations, Distortions prop_rotated_colors_same = property $ do img <- forAll $ genImage colors (rotate90 img) === colors img • normalizing audio shouldn’t change time length • reversing a list shouldn’t change length Susan Potter Thinking in Properties 2020-08-01 28 / 41
  • 49. Mental Models Deriving Properties: Informal model checking Sometimes you can model the basic state machine of a system simply: • model of interesting parts of stateful system • not exhaustive • thinking in state machine models • generate sequence or call graph of commands • assert pre- and post-conditions or invariants • careful you don’t write a second implementation of the SUT just to test it! Susan Potter Thinking in Properties 2020-08-01 29 / 41
  • 50. Mental Models Deriving Properties: Legacy oracles Replacing legacy systems: • bind to old lib as oracle • assert new rewritten library matches oracle for same inputs • good for e.g. calculation engines or data pipelines • might need large build engineering effort Susan Potter Thinking in Properties 2020-08-01 30 / 41
  • 51. Mental Models Deriving Properties: Does not barf Wrapping lower-level code via FFI: • gaps between foreign input or output types and native types • runtime exceptions thrown for some input values (inform design) • sanity checking FFI wrapping Susan Potter Thinking in Properties 2020-08-01 31 / 41
  • 52. Mental Models Deriving Properties: Metamorphic relations • Running against SUT twice with possibly different inputs • A relation exists between those inputs • Assert a relation exists between the outputs of those system runs An example across inputs and outputs, but the relation between inputs and outputs can be different: x, y ∈ Inputs, x ≤ y, x′ = SUT(x), y′ = SUT(y) then x′ ≤ y′ Susan Potter Thinking in Properties 2020-08-01 32 / 41
  • 53. Mental Models Deriving Properties: Metamorphic relation patterns • Input equivalence • Shuffling • Conjunctive conditions • Disjunctive conditions • Disjoint partitions • Complete partitions • Partition difference Susan Potter Thinking in Properties 2020-08-01 33 / 41
  • 54. Mental Models Deriving Properties: Heckle Yourself! • mutation testing • alter your code until your tests fail • if no tests fail, throw your tests out (curation) • question your assumptions Susan Potter Thinking in Properties 2020-08-01 34 / 41
  • 56. Beyond testing Properties of Delivery Pipelines Property: Source consistency Ensuring fast-forward only ”merges”: main() { local -r mergeBase="$(git merge-base HEAD origin/deploy)" local -r deployHead="$(git rev-parse origin/deploy)" test "${mergeBase}" = "${deployHead}" } set -e main # should exit with 0 for success Susan Potter Thinking in Properties 2020-08-01 35 / 41
  • 57. Beyond testing Stateful Migrations (in production) Properties: pre and post conditions and invariants between migration phases • moving a stateful cluster from one datacenter to another • upgrading Elastic search into a new cluster • online schema migrations of large tables with binlog syncing and atomic rename (e.g. MySQL) Susan Potter Thinking in Properties 2020-08-01 36 / 41
  • 58. Beyond testing Stateful Migrations (in production) Properties: pre and post conditions and invariants between migration phases • moving a stateful cluster from one datacenter to another • upgrading Elastic search into a new cluster • online schema migrations of large tables with binlog syncing and atomic rename (e.g. MySQL) Susan Potter Thinking in Properties 2020-08-01 36 / 41
  • 59. Beyond testing Stateful Migrations (in production) Properties: pre and post conditions and invariants between migration phases • moving a stateful cluster from one datacenter to another • upgrading Elastic search into a new cluster • online schema migrations of large tables with binlog syncing and atomic rename (e.g. MySQL) Susan Potter Thinking in Properties 2020-08-01 36 / 41
  • 60. Beyond testing System Monitoring Property: Connectedness! Given public name for service name: • resolve name to A records (IPs) • ∀ IPs should negotiate TLS handshake • ∀ IPs should make HTTP request with Host Susan Potter Thinking in Properties 2020-08-01 37 / 41
  • 61. Beyond testing System Monitoring Property: Connectedness! Given public name for service name: • resolve name to A records (IPs) • ∀ IPs should negotiate TLS handshake • ∀ IPs should make HTTP request with Host Susan Potter Thinking in Properties 2020-08-01 37 / 41
  • 62. Beyond testing System Monitoring Property: Connectedness! Given public name for service name: • resolve name to A records (IPs) • ∀ IPs should negotiate TLS handshake • ∀ IPs should make HTTP request with Host Susan Potter Thinking in Properties 2020-08-01 37 / 41
  • 63. Beyond testing Production Data Checks Sometimes your generators don’t generate data you see in production! Legacy systems exist with no property-based testing toolchain! • Structured logging can record inputs and results; validate OOB • Run property checks against production inputs and outputs in Haskell :) Susan Potter Thinking in Properties 2020-08-01 38 / 41
  • 65. Wrapping Up In Closing • Not all properties are useful • Initially hard to think up useful properties genMentalModels = Gen.choice [ genAlgebraicLaws, genRelationalLaws, genAbstrationLaws, genStateMachines, genMetamorphicRelations, genHeckleYourCode, genTestingInProduction ] Susan Potter Thinking in Properties 2020-08-01 39 / 41
  • 66. Wrapping Up In Closing • Not all properties are useful • Initially hard to think up useful properties genMentalModels = Gen.choice [ genAlgebraicLaws, genRelationalLaws, genAbstrationLaws, genStateMachines, genMetamorphicRelations, genHeckleYourCode, genTestingInProduction ] Susan Potter Thinking in Properties 2020-08-01 39 / 41
  • 67. Wrapping Up Questions? GitHub @mbbx6spp LinkedIn /in/susanpotter Twitter @SusanPotter Web Personal site Consulting Training Thank you for listening! Susan Potter Thinking in Properties 2020-08-01 40 / 41
  • 68. Wrapping Up Credits • Photo by Elias Castillo on Unsplash • Photo by Juan Rumimpunu on Unsplash • Photo by LinkedIn Sales Navigator on Unsplash • Photo by Leonardo Sanches on Unsplash • Photo by Mélissa Jeanty on Unsplash • Photo by Chris Liverani on Unsplash • Photo by <a href=”https: //unsplash.com/@spanic?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText”>Damir Spanic</a> on <a href=”https://unsplash.com/s/photos/baseball-bat?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content= creditCopyText”>Unsplash</a></span> • Photo by <a href=”https: //unsplash.com/@serrah?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText”>Serrah Galos</a> on <a href=”https://unsplash.com/s/photos/reflection?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content= creditCopyText”>Unsplash</a></span> • Photo by Sergey Zolkin on Unsplash • Photo by Roman Mager on Unsplash • Photo by Miguel Ibáñez on Unsplash • Photo by Science in HD on Unsplash • Photo by Steve Douglas on Unsplash • Photo by Natalie Parham on Unsplash Susan Potter Thinking in Properties 2020-08-01 41 / 41