A look at the key principles of writing effective Unit Tests.

F Fast

Unit Tests should be fast.

A suite of unit tests should provide very quick feedback as to the success or failure. It's important that Developers are not put off running the tests because they take took long. Ideally the whole suite should run in milliseconds (or seconds), but not minutes. The value, certainly for TDD is to get instant feedback on changes.

Each Unit Test should be standalone and not dependant on any other test

Tests should be isolated from each other and also the externals of the wider system.
Test the smallest unit you can in isolation and set up each test using the 3 A's

  • Arrange
  • Act
  • Assert

Each test should arrange the test data, act on the class under test, and assert the results.

Tests should be repeatable

It should be possible to re-run the tests with the same result every time. No dependencies on environment/time or external systems. This also includes data i.e no random data and clear down test data from previous runs to start clean each time.

Tests automatically pass or fail

It should be obvious without any external or manual input as to the result of the tests.

T Timely

Tests should be written at the same time as production code

TDD states that tests are written before the production code, but even without using TDD its beneficial to write test code as close as possible time-wise to production code.
Chasing test coverage months or years later seldom produces good quality test code, in some cases they are so heavily mocked that they add little or no value. In this case Integration or System tests may offer a better solution.

What to do with failing, skipped or commented out tests?
Fix them, or delete them. Broken tests add no value.

Mike Jenkins