Software Testing Is Now Every Developer’s Job
One of my coding instructors fondly refers to software testing as “the vegetables of coding.”
Yet more and more companies are prioritizing testing earlier in their software development lifecycles, to aim for a better user experience (aka the shifting-left on the project timeline).
Vágó colorfully describes testing as, “The padding between your software and the customer’s happiness. The thinner that padding, the less happy the user is, and the more you’ll feel their frustration.”
To state this in basic terms, testing is a “combination of process, actions, and code” created with the purpose of confirming that everything that’s meant to happen on the site happens correctly and reliably before the end user has a chance to interact with it.
Testing answers the question: do the solutions satisfy the requirements?
Fine. Testing can be a little sexy. Vágó came in strong early on with some facts about how testing took a man to space. Outer space. Sixty percent of the Apollo Guidance Computer’s development effort was software testing.
If testing is good enough for NASA, it’s good enough for the rest of us.
The Testing Pyramid
Unit Testing: An easy way to understand unit tests is that unit testing tests each individual unit of the application. This is great for testing functions with inputs and outputs, helper methods, objects, procedures, and modules. If it has or more input and an output, it likely needs a unit test.
Integration Testing: A great way to understand integration testing is that integration tests test how well all the units integrate with one another. This is testing for a behavior rather than an output. If this button is clicked, does it behave as expected? Integration testing excels in testing isolated scopes of UI but not for testing for major application flaws.
End-to-End Testing (E2E): Vágó calls end-to-end testing, “the big kahuna of tests.” E2E tests the overall application — all user flows against all relevant dependencies. The testing environment is as close as it can be to a live production environment or in some cases, the production environment.
But what layer is the most important? It depends on who you ask. There’s as much debate on the internet about this as there is about everything else on the internet. It’s so passionate that Vágó refers to the debate as “religious zealotry” on which layer is most important.
But in truth, no matter which tests you implement, you can’t go wrong because all three levels of the pyramid are necessary. Writing unit tests, integration tests, and following those with E2E testing to further validate one’s flows can greatly improve the end user’s experience. A good test can uncover architectural problems and less than desirable UX. It’s not an “either/or” situation.
Too Many or Not Enough
Failing to consider edge cases creates the not-enough-tests category. A considerable percentage of production bugs result from unexpected scenarios so test for the unexpected. If a text input is expecting a string, what happens if the input receives an empty string? If the string is a name what happens if it’s all characters or blank spaces? Roll with it. If 100% of the expected results are tested the unit isn’t tested at all.
There are a lot of specific scenarios that fall under the too-many-tests category but one thing they all have in common is overlap and the skill of doing a cost-benefit analysis (time/$$$). Consider the case where there is a large overlap between unit and integration testing. If everything is integrating properly then it’s also functioning as intended. It’s often necessary to balance the available testing tools to properly allocate resources and priorities.
Another example highlighted in the too-many-tests category is a more specific instance of an application using React Testing Library and Cypress. There’s a running maintenance cost involved with a heavy layer of E2E alongside an equally heavy set of integration suites. So in this case, if the application has very heavy integration testing, consider slimming down the E2E to overall flows rather than testing everything.
A Quality Culture
But It’s Not My Job…. Surprise! Testing is everyone’s job! Long gone are the days (if they ever existed) when the workflow was to write code and then send that code along to the QA team for all testing and bug reports. If the QA team is spending twice the time testing and writing bug reports than the developer spent writing the code, there are more problems than just a few bugs.
A great way to encourage quality testing is to build time into the sprint that allows for proper testing. Twenty-five to forty percent of the sprint time is recommended as the amount of time needed to prevent bugs through robust testing. Imagine what could change if testing is a forethought rather than an afterthought.
Testing doesn’t have to be done alone; share tricky test cases between teams. Create an impact sheet that can track testing vs bugs. Bugs are inevitable but many of them are preventable. Implementing good testing practices doesn’t have to be zero to 100 right away. Starting anything new or even improving something takes time. Even starting with 50% coverage will gradually grow to 70% and 70% will gradually grow to 100% in the not-so-distant future.
Testing and solving unique QA issues is actually everyone’s responsibility, a part of good, daily development practice rather than a “bonus” effort. Vágó said it best, “Perfection is overrated, but making an effort isn’t.”