Your software development team released an MVP application into production. The application only had a few features and the codebase is far from perfect, but there are big plans for the future! Your team presses on, adding features and your user base continues to grow. After a few months, cracks begin to surface. Users started reporting issues and developers get sidelined to fix problems appearing in production. Your release cycles slow as pressure mounts to manually test a growing list of features. Someone asks your development team why issues keep arising. Your team replies “We haven’t had sufficient time to create enough automated tests. Do you want us to invest time testing or do you want us to continue releasing more features as quickly as possible?”
Teams often struggle to find the right balance between testing and developing new features. Software engineering discussions often herald the value of automated testing, but when teams feel the pressure to meet deadlines, it is often the first initiative to get cut. To prevent teams from making short-sighted decisions around testing, everyone involved needs to understand the business value that testing brings.
Automated testing is much more efficient than the series manual checks done before a release, but it is much more than that. Automated testing greases the wheels of good development teams. Because tests can get run quickly and regularly, tests provide feedback and documentation to developers about what the code should do. Even while tests get authored, they inform software engineers of whether they are meeting requirements and keeping a maintainable codebase. Testing is a software engineering practice that gets more valuable over time.
Prevent Bugs in Your Product through Automated Testing
Most people involved in application development are familiar with the concept that robust testing prevents bugs. But it is important to remember how this works. Tests help teams prevent bugs from appearing because they help define the requirements in code. This prevents regressions with new features breaking existing functionality. A developer may complete the work they get assigned, but they usually don’t track all the other functionality their code touches, especially in imperfectly architected applications. By creating tests, the team is validating both current and future code changes.
When tests do their job effectively, they may get under-appreciated because the development workflow proceeds with minimal bugs and issues. When an issue gets reported in production, teams should take it as a reminder of the importance of proper testing. When an issue is fixed is the opportunity to avoid the issue from appearing again by writing tests that prevent the next developer from making the same mistake.
Automating Testing Allows Teams to Develop New Features Faster
For an individual feature, writing tests may seem like it only slows down development. However, tests make it significantly easier to add features in the future. From a developer’s perspective, changing untested code is a risky proposition. You either have to read line-by-line through the code until you understand all possible scenarios, or you push ahead with the change you think you want and hope that you don’t break existing behavior. Tests reduce the risk of changing existing code dramatically.
By defining the use cases that the software is handling, tests provide developers with a roadmap for understanding the important application scenarios. Each test case documents a different facet of the component being tested and how it should get used, functioning as a form of knowledge transfer from the original engineer(s) on the project. Having these kinds of test cases gives developers more confidence to make necessary changes to code they didn’t create. This means teams can more easily work together on features and onboard new developers to the project.
Testing Allows Teams to Ship Faster
Without automated testing, deploying code requires more manual testing. This becomes a barrier to quickly releasing new software. To get a critical bugfix into production, your team needs to be able to quickly release the fix to prevent loss of productivity. This can be especially arduous if your manual testing involves either large amounts of data input or multiple steps for each test case. Automated testing provides superior accuracy for comparing data sets and quickly working through multi-step cases. If a bug gets found during the release process, the test suite can get updated and quickly re-run. Employees provide more value through defining application behavior than executing the same manual steps repeatedly in perpetuity.
Some teams take automated testing to the extreme and use it as their primary metric for when they can deploy their code without issues. These teams employ little or no manual testing and therefore are able to release code daily or many times a day. Automated testing doesn’t mean that all manual testing should get eliminated. But automated testing can drastically reduce the time employees need to spend on manual testing time for a release and therefore allow new features to get to users more quickly and more frequently.
Testing Encourages Better Software Architecture
If code is difficult to test, it often indicates a problem with the software architecture. Source code that requires significant setup to test may be too interconnected with its dependencies making it harder to change with changing business requirements. Code that is slow to test may have performance problems. By writing code that is testable, architectural issues are addressed before they become technical debt that will need to be addressed later.
A good testing suite also encourages improving code by refactoring. There are always opportunities to make code faster, easier to understand, and easier to change. Developers often see these opportunities for improvement when developing, but fears about gaps in testing impede progress. Refactoring provides real improvements to users in terms of performance, stability, and improved ability to make future changes. But without a test suite, refactoring becomes too risky.
Testing is an important aspect in ensuring software works as expected. This is true for both new and old code. Teams with a culture of good testing practices see the benefits compound as software grows in size and complexity. Existing tests give developers and product owners confidence that new code can get added quickly without introducing bugs and regressions. The full testing suite allows teams to ship software faster by reducing the amount of manual testing required. Finally, testing improves the quality of the software written by highlighting architectural issues and allowing developers to make small improvements over time that clear the way for future growth.
The benefits of testing are great. However, not all tests introduce value. Teams often see the value of testing and put a burst of effort into expanding their testing suite only to see tests slow down development. Knowing what to test and how to test are two of the key questions for any software development team. Part two of this two-part automated testing series dives deeper into writing tests that work.