There is no software without testing. I’ve read plenty about TDD and understand the general idea of writing functions to pass pre-written unit tests. But as my worldview expands, I’m realizing how much more there is, and how very vital testing is to software development. Today I’m taking a deeper dive into the role of QA and software testing.
You’ve likely heard of the Software Development Life Cycle (SDLC), of which Testing is one major step. Of course, testing is not limited to that one segment of the cycle. Testing and QA is one of the most integral pieces of the software puzzle, and it’s critical that testers are involved in all aspects of software development.
Much like software is thoroughly planned before a single line of code is written, test plans are created upfront to detail how the software will be tested. Software test plans might include, among other things:
- An analysis of the product: who, what, why, how?
- A high-level test strategy, including test objectives and estimated cost
- The testing scope: which parts of the product will be tested, and which will not?
- The type of tests to be done (more on that later)
When I think of testing, my mind instantly goes to unit tests which focus on individual functions or “units” — the smallest pieces of code. But I’ve discovered there is a lot more out there. A good starting place to think about the different types of testing is the Agile Test Pyramid.
These are various representations of the Agile Test Pyramid, all highlighting slightly different types of testing. But the general idea is the same, and I like this picture because it exemplifies the difference between traditional and Agile viewpoints on testing.
As illustrated, traditional software testing methodologies places an emphasis on manual testing. Bugs are identified post-development, and are then corrected. As I come from a healthcare background, I think of this method as “treatment” — you’re working toward solving a problem that currently exists.
The right image flips this idea upside down (literally). The Agile Test Pyramid places a strong emphasis on unit testing to prevent bugs from the start. This is what I’d think of as “preventative” care in the medical world — taking precautions upfront to prevent bugs from popping up later on.
There are two broad types of software tests: Functional and Non-Functional. As the name suggests, functional tests assess the functionality of a program — does it do what it is supposed to do, per the client’s specification? Functional tests involve comparing expected and actual output to a given input. Examples include:
- Unit tests: test functionality of individual functions or components
- Integration tests: test the ‘integrate’ of multiple units, that they function as expected when working together
- Smoke tests: test most fundamental functions of program
- API tests: verify correct responses from API based on the request
- Acceptance tests: verify that product meets requirement specifications
Non-functional testing is more performance-focused. It looks at the system’s readiness to handle potentially unexpected inputs. Examples include:
- Stress tests: push software beyond its limits (excessive database load, continuous input, etc) to determine when/if it fails
- Reliability tests: verify that software operates error-free for a specified amount of time in a specified environment
- Security tests: look for security vulnerabilities or threats to a product
This is just a tiny sampling of all of the tests out there and many of these can either be performed manually or automated. Automated tests are often integrated into CI/CD pipelines to catch any errors prior to deploying.
CI/CD is an acronym I saw a lot when starting to code but didn’t really understand until recently. It stands for Continuous Integration/Continuous Delivery, and is an Agile best practice. The integration piece is related to committing code changes, while delivery is related to the pushing of those changes to deployment. The essence of CI/CD is to automate deployment so that changes can be made frequently and reliably. Integrating automated tests into CI/CD pipelines is key to ensuring that pushed code is bug-free.
I used to think that QA lives in the show of development. I’ve come to realize, however, that there is no product at all without effective testing. We must embrace the destructive mindset — how can we break this apart in order to ultimately build it back better?