12 Testing Functional Programs

 

In this chapter you will learn how to

  • test pure functions by providing examples
  • test pure functions by providing properties
  • test side-effects without using any mocking libraries
  • develop new functionalities in a test-driven way

Beware of bugs in the above code;

I have only proved it correct, not tried it.

— Donald Knuth

12.1 Do you have tests for that?

The last chapter of the book is devoted to one of the most important software engineering activities: testing. Tests are one of the major methods of writing maintainable software. They can be used to make sure the program behaves according to the requirements, it doesn’t have bugs we discovered earlier and that it integrates with external APIs, services or databases properly.

On top of all that, we can also use tests to document the application: to help understand the responsibilities and inner working to other team members. This is the best kind of documentation because it can’t get outdated as easily as normal text-based documentation usually does—assuming that the test itself is easy to understand. That all makes tests a very important element of a well-developed, readable and maintainable software.

Having an application that consists mostly of pure functions that operate on immutable values makes writing test a very enjoyable endeavor. The tests in this chapter are small, readable and they cover a lot of production code.

12_14

12.2 Tests are just functions

12.3 Choosing functions to test

12.4 Testing by providing examples

12.5 Practicing testing by example

12.6 Generating good examples

12.7 Generating properties

12.8 Property-based testing

12.9 Testing by providing properties

12.10 Delegating the work by passing functions

12.11 Understanding failures of property-based tests

12.12 Wrong test or a bug?

12.13 Custom generators

12.14 Using custom generators

12.15 Testing more complicated scenarios in a readable way

12.16 Finding and fixing bugs in the implementation

12.17 Coffee Break: Property-based tests

12.18 Coffee Break Explained: Property-based tests

12.19 Properties and examples

12.20 Requirements coverage

12.21 Testing side-effectful requirements

12.22 Identifying the right test for the job

12.23 Data usage tests

12.24 Practicing stubbing external services using IO

12.25 Testing and design

12.26 Service integration tests

12.41 Summary