Skip to main content

See tests as living documentation

Tests are often treated as write-once-never-look-at-again code (unless just maybe if there is a bug). That is a shame, because it wastes much of the potential value tests can provide. Good tests are helpful for understanding a piece of code, and making code easier to understand is important since code is harder to read than to write.

To help make code easier to understand, I suggest that you should start looking at your tests as a living documentation of your code. View them as something that your colleagues will look at to understand the code. See them as something that you will look at to understand the code (later).

Focus on communication and intent #

Why? Well, obviously, because they hopefully help you understand the code quicker. But it goes deeper than that – I believe it helps you write better implementation code. The reasons is that it helps you focus on communication and intent, rather than technical details. Because after all, the most important audience of code is not computers, but humans. Computers understand any code that is correct, no matter how it is structured. The same cannot be said for humans. You turn computer-focused tests into human-focused documentation.

Behavior-Driven Development go with this theme to turn tests into a collaboration tool between software developers and business experts.

Seeing tests as stories is an idea I learned from Kent Beck, JUnit’s creator, who said:

Writing a test is really comes down to telling a story about the code. Having that mindset helps you work out many other problems during testing.

What documentation-focused tests look like #

A few examples of how viewing tests as documentation can affect your test writing.

  • Your start using longer, more descriptive method names.
  • You name test methods not only after the method they are testing, but describes what to expect.
  • You use multiple test classes for the same implementation class, separating groups of related tests. (These groups are called “fixtures” and are how JUnit was designed and intended to be used.)
  • You start sorting test methods in a way that makes them easy to grasp.
  • You accept somewhat higher duplication in your tests because readability of tests is so important.
  • You avoid abstract super classes for test classes as they make individual test classes harder to read.
  • You write tests before implementation code to help you focus on the purpose of the code.
  • You realize that the tests needed to drive design in Test-Driven Development are not necessarily the tests needed to show the intent of the code.
  • You understand that deleting tests comes down to story telling – which tests are needed to tell the story about this code.
  • You don’t obsess over 100% test coverage since you get less in return for each test you add.

Updates #

  • 2024-04-24: Republished this post which was originally written for my previous blog.