In this article, we’ll talk about unit testing and Test-Driven Development (TDD). We’ll elaborate on those topics in detail and compare them. Moreover, we’ll see why testing the software is so important.
2. Unit Testing
Unit test is usually a method that validates a small portion of the source code. So, the unit test is a programmatically written, automatic test. The unit test takes the initial data, passes it to the code under test, and asserts if the execution result is the same as the expected result:
Let’s see an example. Assume, we have a method that sums two numbers:
The unit test for such a method would look like this:
As we can see it looks simple. Although writing efficient unit tests could be complicated depending on the code we want to test. A well-written unit test should be:
- Fast. A single project can contain a big number of unit tests, even hundreds, or thousands. Moreover, unit tests can be executed often, e. g., while developing a new feature to avoid regression or in CI/CD pipelines. Therefore, they must run as fast as possible.
- Isolated. A unit test shouldn’t modify or depend on any external state.
- Deterministic. A unit test should always return the same result no matter how many times we execute it. Of course, if nothing is changed between runs.
- Readable. Unit tests are code that needs to be maintained. Therefore, it should be clear and easily understandable.
- Simple. Often we can read that the unit test should contain a single assertion. Although it can be discussable, the fact is unit tests should validate small portions of the source code.
3. Why Unit Tests Are Important?
We already know how to write unit tests. Let’s describe the benefits they bring. First of all, it ensures that the code works as intended. We can write unit tests for different scenarios, edge cases, and parameters.
Secondly, we can run those scenarios whenever we need them, e.g., while working on the code. It saves time, as going through all of those scenarios manually would be surely time-consuming. Moreover, fast and easy testing while working on the code helps avoid regression in existing features.
Next, writing unit tests improves code quality. That’s because testable source code needs to be well written. Therefore classes and methods are automatically smaller and more specific.
An important benefit of unit tests is that they reduce the total cost and time of software development. Early bugs detection results in easier and faster fixing than if done later as the project grows.
Last but not least, a maintained unit test creates always actual documentation that describes the purpose of code under test.
TDD is an approach to software development in which the unit tests are written before the business logic. In other words, developers write unit tests for the feature before implementing it. Let’s describe a TDD workflow:
A TDD cycle consists of three stages:
- Red – during this stage we write a test for functionality that is not yet implemented. We need to run the test to ensure it’s failing. Otherwise, we’ll get a false positive which means the test is badly written. Most popular IDE’s displays test failures using red color. That is why the stage is called red.
- Green – during this stage we write enough code to just cover the test. We should focus on covering the test, not on the code quality. We write a minimum amount of code to pass the test. IDE’s often signals passing tests with a green color. So, the stage is called green.
- Refactor – final stage, here we focus on improving the code quality. Therefore, we should make all refactors needed to improve the code. While making changes, we can run the tests to avoid any regression.
To write appropriate unit tests before the logic developers spend more time on analyzing and understanding the problem and its domain. Therefore, the code is more likely to meet all requirements and clients’ needs. It’s one of the most important aims of TDD.
The cycles play an important role, as the tests become more specific with time while the implementation becomes more generic.
TDD is a broader concept than unit tests. TDD is a software development approach focused on understanding the problem domain and fulfilling the requirements. Bare unit tests are about validating the written source code and avoiding bugs and regression. In fact, unit tests are part of the TDD cycle.
Secondly, while using TDD unit tests must be written before the feature that they cover. While bare unit tests can be written at any time, e.g., during or after the feature development.
Last but not least, TDD requires the cooperation of all parties involved in the project. Whereas bare unit tests are mainly the developer’s responsibility.
As we can see, TDD and unit tests are significantly different concepts. Although they’re connected at some point, ass TDD partially relies on unit tests.
In this article, we elaborated on unit testing and TDD. We describe the principle of both and compare them. We clarified that TDD is a broader concept than unit tests, as it’s a whole software development approach with a specific work cycle. Whereas unit tests can be used with or without the TDD approach and they are beneficial for the project in a variety of ways that we mentioned.