chapter fourteen

14 Testing F# code

 

This chapter covers

  • When and when not to test your code
  • Making testable code
  • Basic unit testing
  • Working with NUnit-style testing frameworks
  • Property-based testing

This chapter focuses on writing automated tests of your F# code. There are entire books dedicated to unit testing, and I’m not going to try to cover everything in this chapter. Many (but not all) of the things you’ll read in those books still apply to F#, so as with other areas of the book, I’ll instead focus more on testing from an F#, FP-first perspective.

14.1 Automated tests: The value proposition

This section is a broad overview of the idea behind automated tests and how automated testing generally fits within the context of F#. Although I briefly covered the idea of unit tests and a process for writing them known as test-driven development (TDD) earlier in the book, if you’ve never written any automated tests before, you’ll want to know what they are and why you should bother with them. Automated tests are simply code you write (so-called test code) that tests the actual (“production”) application code of your system. Typically, they’ll set up some initial state of the application with some predefined input data, then call some production code, and then test the state of the application again to ensure that the production code has had the expected effect. Tests like this are typically short lived, fine grained and should be highly consistent and reliable.

14.1.1 F#: Types over tests

14.2 Basic unit testing in F#

14.2.1 Tests as functions

14.2.2 Expecto

14.2.3 Plugging Expecto into our code

14.2.4 Advantages of Expecto

14.3 Making testable code

14.3.1 Preferring pure functions where possible

14.3.2 Preferring smaller functions

14.3.3 Unit testing small function hierarchies

14.3.4 Integration testing higher-level composed functions

14.3.5 Pushing side effects to the boundaries of your code

Summary