I started exploring the fascinating world of test automation seven years ago. Right from the start, it was clear to me that testing has important benefits. Anywhere I read back then, I found people describing how testing leads to savings in development time and more robust software, among other things.
However, after all of these years of practice, I have learned some benefits that were less obvious to me when I started.
In this post, I share them.
Maybe, when you read this post, you think that these benefits are basic and well-known. That’s fair. My claim is just that they were not obvious to me when I was writing my first automated tests.
My lack of awareness at that time is the main motivation behind this post. If I can make only one person discover these benefits quicker than I did, then my goal will have been achieved. If I can convince only one unconvinced person of the usefulness of testing, then this post will have gone far beyond my initial expectations.
1. Tests give you code samples.
Have you ever skipped an answer in StackOverflow because it didn't contain a code sample?
We look for code samples because they help us understand how things work.
Automated tests play the role of code samples. Each test represents an example of how the system is used at the code level; therefore, they are of invaluable help when we are trying to understand the system better.
A software system is easier to understand if it has automated tests in place.
2. Tests give you executable specifications.
Written documents become obsolete easily, so they often lie. They specify what the system is supposed to do, not what it really does.
The only truth about the system behavior is in the source code. The code brings this behavior to life and makes it possible; the tests specify, document, and enforce it, in a formal and unambiguous way. Therefore, automated tests are executable specifications of the behavior of the system. If this behavior changes, the tests will fail. If we want to change this behavior, we must adapt the tests.
Tests specify how the system actually behaves and they are always up to date.
3. Tests give you the first users of your code.
When you are writing tests, you become a user of your own code. If the code is bad, you are the first to experience the problem. This makes you put more effort in refactoring, and in writing clean code and clean tests.
When you want your tests to be clean, you will choose better names for your variables, functions and classes. This improves the readability of your tests, which, in turn, improves the readability and design of your code, which, in turn, makes testing easier. It is a self-reinforcing loop.
A good testing strategy leads to cleaner code.
4. Tests give you immediate feedback about code changes.
Have you ever felt the pleasure of misspelling a variable name and getting immediate feedback from your IDE?
Your IDE warns you about this kind of errors because they are syntactic issues that can be detected via static analysis at compile time. But, you can get the same kind of feedback about runtime errors. You only need fast tests that you can run after every change in your code.
For example, if you replace “+” with “-” by mistake, you will change the semantics of the code and therefore its runtime behavior. If the tests are semantically stable, they will detect the error immediately.
Automated tests shorten the feedback loop on coding decisions.
5. Tests prevent the occurrence of bugs.
Having quick feedback on coding decisions has a significant consequence: bug prevention.
Tests specify the behavior of the system. As long as the tests are there, this behavior is preserved. If, sometime in the future, you change this behavior unintentionally, the tests will catch the error. This error, which might have been detected months later, has a lifetime of less than a few seconds.
Tests help you detect errors early, when they are cheapest to fix.
6. Tests give you a safety net.
With a good suite of tests in place, you can modify code, run the tests, and immediately know whether you altered the system behavior. In other words, you can modify code safely.
This is where the safety net metaphor comes from. Automated tests act as a safety net that allows us to refactor confidently, in a similar way to trapeze artists to perform without fear of being hurt. But, nets can contain holes through which we may fall. These holes take the form of untested behaviors, where potential bugs may hide.
Automated tests protect us from unexpected, and potentially harmful, events. But, test suites must be comprehensive, if we want them to meet this goal effectively.
7. Tests have positive architectural implications.
To test a unit of code properly, we must isolate it from its dependencies. This is typically accomplished through the use of test doubles, also known as mocks.
When the code is highly coupled and dependencies are hard-coded, isolation becomes difficult and testing sometimes prohibitive. This implies that, the more loosely coupled a system is, the more of it can be verified in terms of unit tests. In other words, the lower the coupling, the higher the testability.
Automated tests lead to low coupling and higher-quality design.
If we consider all of these benefits together, we can reach an important conclusion:
Automated testing dramatically increases software quality.
And high quality is the only way we can have:
- Ability of respond to change quickly.
- Huge savings in time and money.
- High customer satisfaction.
- A motivated development team.
In this new era of uncertainty that we are currently living, all of these advantages may be more necessary than ever before.