Unit Testing for Complex Features
At WorkingMouse, our experimental framework continues to evolve as we adapt to new technologies and ways of working. We encourage all team members to propose experiments, trial them, and document the results. Some experiments are widely adopted, while others are learning experiences. This blog shares the findings of a recent successful experiment involving unit-test-driven development for complex features.
Summary
Our scientific structure guided the experiment, looking at why, what, and how. The current landscape emphasizes end-to-end (E2E) testing, which simulates user behaviour. However, as the complexity of systems increases, we believe that writing unit tests before implementing changes results in faster implementation and reduces risks. We experimented by writing unit tests for a feature with complex logic before implementing the actual change. The experiment’s success criteria were simple: the unit tests must pass, the change should be implemented without issues, and it must pass UAT (User Acceptance Testing).
End-to-End Tests vs. Unit Tests: The 2024 Perspective
The distinction between unit testing and end-to-end testing remains crucial. Unit tests focus on smaller, isolated pieces of code—such as a function or algorithm—while E2E tests simulate the entire application’s workflow. Modern tools like pytest and Selenide allow developers to create reliable, scalable tests that handle complex workflows with greater precision.
While E2E tests continue to play a significant role, especially in user interaction simulations, we have seen an increase in the use of unit tests in long-running projects. With the growing adoption of Continuous Integration/Continuous Delivery (CI/CD) pipelines, unit tests are crucial for maintaining stability during frequent releases.
Method: Test-Driven Development (TDD)
To evaluate the success of this experiment, we employed test-driven development (TDD) for four complex functionalities in a public sector project. Following the Red-Green-Refactor model, we first wrote the unit tests, then implemented the code to pass them. While we continued to write E2E tests, the unit tests proved more effective at catching bugs early and reducing maintenance costs.
Evaluating Unit-Test Driven Development
Here’s what we found:
• Unit tests were highly reliable, showing zero false negatives, whereas our E2E tests frequently had false negatives, which required troubleshooting.
• The maintenance effort for unit tests was minimal, unlike the E2E tests that demanded about 1-2 days of maintenance effort per week.
• Our confidence in areas covered by unit tests was significantly higher. Additionally, CI/CD integrations made running these tests quick and efficient.
• Unit tests helped identify bugs earlier, saving time and cost by reducing the number of issues that slipped into later stages of development.
Going Forward: 2024 Testing Strategies
Unit testing, especially when used in conjunction with E2E tests, is a powerful tool for long-term projects. They are not a replacement for E2E tests but are particularly useful in areas where logic is complex and where frequent maintenance is required.
In 2024, AI-driven testing tools are increasingly common, enabling teams to automate test generation and optimize their test suites. This allows for more efficient use of both unit and E2E testing strategies. We encourage our team to leverage unit tests wherever they would add value, especially in long-running products.
Industry Best Practices
Industry leaders like Google have long advocated for the benefits of unit testing, emphasizing its speed, reliability, and ability to isolate features. Today, the use of modern testing frameworks such as pytest and PHPUnit in combination with CI/CD pipelines, significantly enhances development workflows.
Conclusion
In 2024, unit tests remain a vital part of our testing toolkit, especially for complex features. They complement E2E tests by offering more precise, low-maintenance coverage, allowing us to deliver reliable software faster and with fewer bugs.