-
intro - what property tesing does
- there and back - deserializing the output of a serialzier
- & 3: test examples require imagination to be thorough
-
some mathematical properties for pure functions
- idempotent:
f(a) = f(f(a))- repeated calls have no further effect
- involutive:
a = f(f(a))- repeated calls reverse the effect
- commutative:
a + b = b + a- order of arguments doesn't matter
- distributive:
f(a+b) = f(a) + f(b)- order of operations doesn't matter
- associative:
a + (b + c) = (a + b) + c- grouping doesn't matter
- generally applies to any concatenation-type operation
- identity operations
f(a,b) = a where b = 1- there's a special argument that makes the operation return the other argument
- zeroing operations
f(a,b) = b where b = 0- there's a special argument that makes the operation return the special argument
- injective operations
f(x) = z & f(y) = z ∴ x = y - bijective operations
- all inputs map to exactly one output, and vise versa; operation is therefore reversible
- reverse
- push/pop, shift/unshift
- serializers/deserializers, encoders/decoders
- idempotent:
-
mindset, other ideas for application
-
mindsets Easier:
- things "mathy" in nature
- "pure" operations with no side-effects
Medium:
- things involving state / dependednt operations
- things with complex inputs/outputs
- side effects that are deterministic
Harder:
- things with opaque state
- non-deterministic side-effects
Notes:
- triangle inequality: https://en.wikipedia.org/wiki/Triangle_inequality
- what are the boundaries of the thing I'm testing?
- what does the thing I'm testing actually do?
- Matthew's Three Types of Bugs
- it doesn't do what it's supposed to
- it does what it's supposed to do, but what it's supposed to do is wrong
- we don't like what it's doing, but we're not sure what it's supposed to be doing either
-
equivalent / reference implementations
- various sorting algorithms
- query engines:
- generating data for the database, variables for query
- parallel implement query operation in code (which is presumably more readable/predictable)
- does the database query results equal the code results
-
state machines
- generate sequences of operations
-
race conditions
- generate sequences of operations over time, validate nothing bad happens
-
UI fuzzing
-
random data for fuzzing
-
random data for demos
-
abuse them as solvers
- water pouring puzzle: https://en.wikipedia.org/wiki/Water_pouring_puzzle (prettier example of this for Python's Hypothesis: https://hypothesis.works/articles/how-not-to-die-hard-with-hypothesis/ )
-
-
generating values This part is tedious, varies highly from library to library
in general, you are building a Rose tree: https://en.wikipedia.org/wiki/Rose_tree each branch / leaf has a notion of magnitude, and can be "shrunk" or removed
I suggest composing from primitives and mapping/filtering them into "subtypes"
-
some language libraries:
- the OG QuickCheck: https://hackage.haskell.org/package/QuickCheck
- JavaScript & variants: FastCheck https://fast-check.dev
- Clojure (where I was introduced to it): https://github.com/clojure/test.check
- .NET: FsCheck https://fscheck.github.io/FsCheck/
- Go: Rapid https://github.com/flyingmutant/rapid
- Java: Junit-Quickcheck https://github.com/pholser/junit-quickcheck
- Python: Hypothesis https://hypothesis.works
- Erlang: Proper https://github.com/proper-testing/proper
- Swift: SwiftCheck https://github.com/typelift/SwiftCheck
- Ruby: Rantly https://github.com/rantly-rb/rantly
and so many more: https://github.com/topics/quickcheck
-
Notifications
You must be signed in to change notification settings - Fork 0
mattly/ssdug-property-testing
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published
