Good tests are the best documentation

Return to overview
Four different flasks

Why do you test? Is is because you want to prevent errors on a deployment affecting the visitor? Is it because you simply want to know that the software does what it needs to do? Or maybe you want to get to know the software a bit better?

Hopefully, in this day and age, your main software tests are automated. Running before a commit, running in the deployment pipeline and running on a testing environment. Repetitive jobs need automation and testing fits that mantra very well. This article is relevant for automated testing, although for certain topics you could use a manual testing perspective as well. If you like.

So to the topic at hand: what are tests exactly? Obviously they are scripts that assert certain actions on the software that it's running against. If they pass, your software should work as expected (provided you've written decent tests). Having software that can be asserted helps you in changing the software (refactoring, adding features) without impacting the existing feature set. That at least, is one part of testing.

In the above case, we're considering tests that are being executed after the development is done. More of a Feature Driven Development (FDD), where tests are mainly a form of (re)assurance.

When we are entering the realms of Test Driven Development (TDD) on the other hand, we're using tests as a way of describing software. Describing it even before the software is built. This way, testing becomes a tool that helps stakeholders to have a common understanding (preferably in a language that we all understand) on how software should behave and also how it not should behave.

Test driven development is very useful for fleshing out features and tackling unwanted behaviour early in the process. It also facilitates a closer collaboration within a team, where every member has its own area of expertise.

Whether from FDD or TDD perspective, the tests are asserting if the software works as expected. This means that your test suites are your documentation on how the software should function. Your tests are documentation.

Treating your tests as documentation helps in framing tests in a different way. Please steer clear from unit tests that say: test('should return true', () => { expect(someFunction()).toBeTrue(); });

Why? Well, its not a descriptive line at all. It doesn't provide any context. I need to actually read the assertion and make assumptions on when said function should return true. A better test would be:

test('return value should be `true` if no parameters are provided', () => { expect(someFunction()).toBeTrue(); });

Now the test is actually a bit of documentation. So please take effort in writing tests, because future you will thank you for it.

There are several types of tests, where I think the most commonly used (by development teams) are unit tests, snapshot tests, performance tests and integration tests. All of these tests document a different aspect of the software: how it works on a low level, how parts of it should look like, how well it should respond and finally how features flow through the application.

The best part is that this type of documentation is part of the development process. It's not an outdated document that's hosted on a confluence page of company wiki space. While you're working on the code, you're forced to consider the documentation, because otherwise it will fail.

There is a caveat though. Treating tests as documentation means that you will need to spend some extra effort on it. Preferably you will want to reach a high coverage, which is only easy to measure when you consider unit tests (even that coverage can be misleading or fooled).

I believe the effort is worth it, because it also provides some benefits. You can release more confidently. Everybody on the team should be able to understand tests, which means everybody on the team should be able to understand the software. Having this extensive documentation helps you revisit code much easier, because you have a better understanding on what it does. If revisiting is easier, think what that means for onboarding new developers!

So testing is a documentation silver bullet? Not always. This type of documentation has limits: the software. The coupling is set to a specific scope. You cannot automatically make assertions outside of the software you control. Not everything a development team outputs revolves around software. So some documents will need to be written and manually updated every now and then. That's okay: its a small part relative to the main subject you and your team should be spending time and effort on.

Return to overview