Why Should Developers Write Unit Tests?
While building an app, we really cared about the product quality. Our users’ needs demanded the app to work properly. I had most of the critical parts of code test-covered, with corner cases and multiple paths. It’s an interesting process of finding a bug, fix it, write a couple of tests for the surprising scenario, and be sure it won’t break again.
But I’ve seen many developers who don’t write unit tests. Here are some of the excuses I hear often:
We don’t have time to write tests!
Unit tests are a waste of time. They slow us down and decrease productivity!
I don’t know how to write unit tests!
A Unit is the smallest testable part of an application. In procedural programming, a unit may be an individual program, function, procedure, etc., while in object-oriented programming, the smallest unit is a class, which may belong to a base/super class, abstract class or derived/child class.
Unit tests are not intended to verify the high-level system or business requirements. They verify that each unit which makes up the system behaves only as expected, according to low-level functional requirements of the application and meets other test objectives such as robustness testing or code coverage. Without confidence in the units, it is much harder to have confidence that the software as a whole will work.
Why writing unit tests is a good practice?
Unit tests enable collective ownership
This states that your unit tests guard against other developers breaking your functionality. Developers are required to ensure all unit tests still pass before releasing any new code, thus ensuring that changes being made do not break another part of the system. Faults introduced by multiple developers working on common functionality can easily be missed, resulting in bugs being delivered to customers.
Thus, unit testing leads to reduced costs for future releases of the system. Implicitly a new revision will involve change, a complete set of unit tests will help ensure that existing features are not broken when new ones are added.
Unit tests enable safe refactoring
Refactoring is a very common activity in modern OO development and is an activity where it is very easy to introduce bugs. A complete set of unit tests will ensure that refactoring does not introduce an unexpected bug.
A comprehensive unit test suite enables major refactorings and restructuring of the code base to be completed with greater confidence. As long as unit tests continue to pass, developers can be confident that their changes to the code do not have a negative impact on the functionality of the application as a whole.
Problems are found early in the development cycle
The cost of fixing a bug increases the later it is found in the development cycle. Consider the cost of a developer discovering a bug in his code at unit test time. At this stage, the only changes will be to the code, and possibly the design document. Now imagine the costs if this bug were to get to system acceptance. At this point, the code and design will still need updating, but now integration and system level tests will need to be rerun, with further updates possibly being required. It should also be noted that it may be very hard to identify and then isolate a simple coding error from any other unexpected failure in the system.
Unit testing cannot eliminate this problem but should significantly reduce the number of iterations required. A code base with a large number of simple errors can be very difficult to debug as some bugs may corrupt a resource used by a different area of the code. In this case, fault finding can be a very arduous task. This type of bug is very easily found in a unit test using negative testing.
Easy Regression testing
Unit testing helps to make sure the code works correctly. Unit-tests are a great way to do regression testing: simply run them every time you change something and make sure nothing breaks. Spotted a bug? Fix it and write a unit-test to make sure it doesn’t happen again.
When to write the tests?
Once you know how to write structured, maintainable, and solid tests with a unit testing framework, the next question is when to write the tests. Many people feel that the best time to write unit tests for software is after the software has been written, but a growing number prefer writing unit tests before the production code is written. This approach is called test-first or test-driven development (TDD).
How Test-Driven Development Works?
At its simplest, TDD is the practice of writing each piece of production code in direct response to a test. The unit test fails; we write the production code lines until the test passes. This is however only a rough description; the actual process is done via below three steps. These steps are called as Red-Green-Refactor.
A. Write a new unit test for a section of code
B. Verify failure of the new test and the success of existing tests. If the new test passes immediately, verify that it is not redundant, then start over at step 1a.
A. Write some code to implement, modify, or develop the unit
B. Repeat until the tests pass. If one or more tests fail, continue coding until all tests pass. If the tests pass, the developer can be confident that the new/modified code works as specified in the test. Stop coding immediately once all tests pass.
A. Refactor the code to improve non-functional code structure, style, and quality
B. Confirm tests pass. If one or more tests fail, the refactor caused problems; edit until all tests pass. If the tests all pass, the developer can be confident that the refactoring did not affect any tested functionality.
Many case studies found that TDD approach help writing higher quality code. This case study from Microsoft shows that the TDD teams produced code that was 60 to 90 percent better in terms of defect density than non-TDD teams. many app developers adopt TDD process for software and mobile app development. Since TDD provides lots of benefits over traditional development approaches like a waterfall, many app development companies have started adopting TDD.
Unit testing is an important error prevention practice that allows you to detect errors, and to modify your organization’s development processes to prevent future errors from being introduced into the code. Performing thorough unit testing reduces allows you to ensure the quality, security, and reliability of your code from the earliest stages of development, and drastically reduces the potential for errors.
You may also be interested in: