For any code to be considered ready for production there need to be tests. For a given change this might include writing Unit Tests1, Integration Tests and End to End Browser Tests. We need to ensure that we have an appropriate level of testing. Our code review process should pick up issues around the appropriate level of testing.

Thoroughly test your own code

If you’re fortunate enough to have support in the form of a QA team or a group of manual testers, that’s great, but ultimately you are responsible for the quality of what you launch.

General Guidelines

Unit tests

Unit tests are a cheap way to test code, and should be included to support and document the behaviour of code. However, they are particularly useful for exercising expected error conditions (e.g. an aborted database transation; a 500 HTTP response).

It can be tempting to mock the system under test, but you should not do this as it results in a restatement of the code, which is overly-coupled to code structure rather than behaviour. Mock at service boundaries instead. Furthermore, think hard before mocking at the service boundary: does the service use file, database, or network I/O? If not, could you use the real service instead?

Integration or end-to-end tests

Integration and end-to-end tests are much more valuable from the perspective of testing workflows. However, they typically do not allow us to exercise specific error scenarios.

Integration tests or end-to-end tests alone are insufficient - things that cannot be exercised in these tests must be covered with unit tests.

End to End Browser Testing

End to End Browser tests are by definition time consuming. In order to ensure that we can keep build durations down we need to consider a number of things when writing them:

If your browser test suite is taking longer than 45 minutes to run, then it’s time to refactor.