Unit testing (preferably boosted by TDD) is one of the best ‘first level’ testing approaches that a software engineer can undertake. It doesn’t always fulfill our needs though. For instance: having a function f() which reverses a collection of numbers, where do we set the line and tell ourselves: “That’s enough. f() is well tested. Let’s move on.”? After 10 test cases? 50? 1000? Instead of checking tens, hundreds or maybe even thousands of combinations of possible input parameters we can check a set of predefined properties about input(s)/output(s) or about our system as a whole. This is called property based testing. So in case of function f() we can simply check that double invocation of f() should always yield the original value passed in - no matter what the inputs are.