The Coverage Trap
Many engineering teams report 80% or 90% test coverage and still ship bugs that bring down production. The disconnect is real: coverage measures which lines of code were executed during a test run — it says nothing about whether the right scenarios were tested, whether the assertions are meaningful, or whether the tests actually fail when the code breaks.
A test that calls a function and asserts that it doesn't throw an exception is not a test. It's a performance. A genuinely useful test exercises a meaningful user scenario, asserts on observable outcomes, and fails loudly and specifically when behaviour changes unexpectedly.
Designing for the Failure Modes That Matter
A QA strategy starts not with tools but with a failure mode analysis. What are the things that, if broken, would cause real harm to users or the business? For a payment platform: incorrect charge amounts, failed refunds, missing order confirmations. For a SaaS B2B product: broken login flows, corrupted data exports, missed webhook deliveries.
These critical paths should be covered by multiple test layers — unit tests on the calculation logic, integration tests on the API contracts, and E2E tests on the user-visible workflow. The long tail of nice-to-have features can tolerate thinner coverage. The critical paths cannot.
The Four Layers Every QA Strategy Needs
A complete QA strategy covers four layers, each with a different purpose. Unit tests verify that individual functions behave correctly in isolation — they're fast, cheap to run, and should be written by developers as first-class code. Integration tests verify that components interact correctly: service A calls service B with the right payload and handles the response appropriately. End-to-end tests verify complete user journeys from browser to database using tools like Playwright or Cypress.
The fourth layer — exploratory testing — is the one most teams skip. Exploratory testing is structured, skilled manual investigation aimed at finding things automated suites don't. A trained QA engineer approaches the product as an adversary: what happens if I submit this form twice? What if the API response is delayed? What if the user's session expires mid-checkout? This is where the genuinely damaging bugs live.
Performance and Contract Testing: The Forgotten Layers
Beyond functional correctness, a production-grade QA strategy needs two additional elements: performance testing and API contract testing. Performance tests — load tests with k6 or JMeter — verify that the system behaves acceptably under realistic and peak traffic conditions. They catch architectural problems that unit tests cannot: N+1 database queries, missing cache headers, connection pool exhaustion.
Contract testing (Pact or similar) verifies that the implicit agreements between services — the shape of the JSON payloads, the error codes returned, the authentication headers expected — remain stable as services evolve independently. In a microservices architecture, it's the primary defence against integration failures that only surface in staging.
QA as a Continuous Practice, Not a Release Gate
The most important shift in modern QA thinking is moving from 'QA before release' to 'QA as a continuous discipline.' This means tests run on every commit, not just before deployment. It means monitoring production with the same rigour applied to pre-production. It means QA engineers are involved in incident reviews, not just sprint ceremonies.
The teams that execute this model well don't have 'release days' — they have continuous deployment pipelines where quality is baked into every step. The release is not an event. It's a routine.