Software Testing Best Practices

Chapter 2 of 8 · 5 practices · 4 min · 3-question quiz

Writing good unit tests

A good unit test is short, readable, checks one behaviour and fails with a message that tells you what broke. This chapter covers structure, naming, table driven cases and edge cases.

Start: Structure every test as Arrange, Act, Assert

5 practices in this chapter

  1. 1Structure every test as Arrange, Act, AssertEvery test does three things: set up the inputs, call the code under test, and check the result. Making those three phases visible, with a blank line between them, means anyone can read a test at a…
  2. 2Test one behaviour per test and name it after that behaviourFowler's rule is to test one condition per test. When a test checks five things and fails, the first failed assertion hides the other four, and the name cannot describe all of them.
  3. 3Use table driven tests for many inputs to the same logicWhen the same behaviour needs checking with many inputs, copy pasting a test ten times hides the one line that differs. Every major runner supports parametrized tests: test.each in Vitest and Jest…
  4. 4Prefer readable tests over clever, deduplicated onesProduction code should avoid repetition. Test code should first be easy to read, because a test is documentation that someone opens only when it fails. Fowler notes that readability matters in tests…
  5. 5Test boundaries and failure paths, not only the happy pathMost bugs hide at the edges: off by one errors, empty inputs, nulls, the exact limit and the value just past it. A suite that only tests the happy path will pass while production breaks.

Check yourself on this chapter

3 questions, right here once you are signed in. Your progress is saved as you read.

Sign up for the quiz