3 Testing techniques

 

This chapter covers:

  • Organising your tests comprehensively
  • Writing assertions which are flexible and robust
  • Isolating and instrumenting parts of your code for tests
  • Strategies for choosing what to test and what not to

Well written tests have two main qualities: they only break when the application misbehaves, and they precisely tell you what's wrong. In this chapter, we will focus on techniques which help you achieve these two goals.

If you've written a test for the addToCart function, for example, you don't want it to break if that function is still working. If the test does break, it will generate extra costs because you will have to spend time updating it. Ideally, your tests should be sensitive enough to catch as many bugs as possible, but sufficiently robust so that they fail only when necessary.

Considering that your tests for the addToCart function broke for a good reason, they still wouldn't be particularly helpful if their feedback was undecipherable or if ten other unrelated tests failed when they shouldn't. A carefully architected test suite provides you with high-quality feedback to fix problems as quickly as possible.

In this chapter, to achieve high-quality feedback and robust yet sensitive tests, I will focus on how to organise tests, write assertions, isolate code, and choose what to test and how to test it.

3.1 Organising test suites

3.1.1 Breaking down tests

3.1.2 Parallelism

3.1.3 Global Hooks

3.1.4 Atomicity

3.2 Writing good assertions

3.2.1 Assertion counting

3.2.2 Loose assertions

3.2.3 Using custom matchers

3.2.4 Circular assertions

3.3 Test doubles: mocks, stubs, and spies

3.3.1 Mocking imports

3.4 Choosing what to test

3.4.1 Don't test third-party software

3.4.2 To mock, or not to mock, that's the question

3.4.3 When in doubt, choose integration tests

3.5 Summary

Organising test suites

Writing good assertions

Test doubles: mocks, stubs, and spies

Choosing what to test

sitemap