Unit Testing

Published date: April 15, 2024, Version: 1.0

Purpose: Unit testing allows Developers to verify that individual "units" of code, such as methods or modules, meet their expected postconditions. Its primary purpose is to ensure that changes, including adding new features or refactoring existing ones, do not introduce errors or impact the correctness of the application. Unit testing is not limited to one-off development use; it plays a vital role in producing bug-free code.

Unit tests should be fast, easy to run, and self-contained. If a unit relies on external dependencies like databases or message queues, these dependencies should be replaced with Test Doubles. Test Doubles mimic the behaviour of the external system, enabling the unit to be tested independently. This ensures that the tests remain isolated and don't rely on the availability or behaviour of external systems.

Some teams or developers advocate for Test-Driven Development (TDD), where unit tests are written to describe the acceptance criteria before implementing the application code. This approach ensures that the code satisfies the desired behavior as defined by the tests. It promotes iterative development and helps maintain reliable and maintainable code.

Unit testing follows isolation testing principles, where each unit is tested independently from the units it calls and the units that call it. Units can be tested in any sequence as no unit test depends on the testing of other units. Test drivers and stubs are used to replace the called units during isolation testing. By isolating units, it becomes easier to thoroughly test their functionality without the complexities of other units. Isolation testing also aids in achieving good structural coverage, and the difficulty of achieving coverage does not vary with the position of a unit in the unit hierarchy. It is crucial to update unit tests whenever the software undergoes modifications or is used in a new environment to maintain their relevance.

The unit test strategy is applicable for custom-built applications but not for off-the-shelf products (except for custom enhancements) or third-party vendors.

It is recommended to automate at least 95% of unit tests and ensure they all pass before deploying the code to the development environment. Automated unit tests are integrated into a Continuous Testing pipeline, and a quality gate is defined with a requirement of a 100% pass rate. This ensures that the code undergoes comprehensive testing and meets the defined quality criteria before proceeding further.