Three different ways to think about Automated Testing
Whether you're starting on a new project or working inside a long-running application, incorporating automated tests can be intimidating. If you don't have a strategy or guiding principles, working on tests can feel like a distraction from building the actual application.
However, a well-built test suite can help engineering teams better collaborate on a application. It can also help make applications run more predictably and allow for more stable refactors.
Here's three different ways you can think about approaching automated testing in your next project.
Tests as Structure
When we build houses or larger buildings, there are different structures inside a building that carry the weight of the rest of the rest of the building. These load bearing walls and beams are important they hold the rest of the building up. During construction, we often need to support them with scaffolding in while everything else gets setup, so that the rest of the building can stay standing. Without them, everything is likely to collapse.
In software applications, there are often code paths and libraries that are critical to the overall functionality of the application.
Automated tests can provide a baseline structure for your project by defining how sections of your codebase should (and shouldn't) work. By enforcing different sections of code to behave in different ways, you can have confidence that the codebase will behave the way you expect it to.
This type of thinking can also be supported by other strategies, such as type hinting. By ensuring that the inputs into functions and methods are what you expect, you can clear out a whole host of issues that often crop up.
Tests as a Design Tool
Writing automated tests can also be a useful way to suss out how an application works without committing to writing out a full implementation. If you're trying to translate functional requirements into working code, it's helpful to have tests available to ensure it's working properly.
Commonly known as Test Driven Development, discussions around TDD over the years tend to push towards extremes of whether or not it's a valuable approach or too much overhead. Personally, I've found it useful to use as a way of building out small parts of logic where the business rules are likely to have side effects and non-obvious edge cases.
While this approach is easier to apply during initial development, it can also be an helpful way to figure out how something works in an existing, untested application. In the same way you might open up a REPL and start manually testing a library, you could also add to your test suite, and mark tests as skip-able or incomplete if you turn up something unexpected.
Tests as Documentation
Well written and organized tests can provide context on how different parts of an application work. This requires an extra emphasis of the readability of tests.
Many of the same strategies that apply towards organizing your codebase apply with tests as well. You want to make sure your test methods are well labeled and organized in logical groups.
Functional and end-to-end tests in particular can be organized more for legibility and to convey specific workflows than the actual codebase itself, which can make it easier to understand how a codebase works.
Treating tests as documentation can pair well with README's, runbooks, and other developer documentation in order to provide a fuller picture of application functionality. When paired with code coverage tools and IDE's, you can even automatically link from your tests to the parts of the codebase being tested!