QA Should Find… Nothing!
As an engineer, I consider it a matter of professionalism to make sure the code I output is as error-free as possible before passing it on to QA. This philosophy has led to great success in QA interactions and more efficient teams throughout my career (this primarily applies to well-established products).
The Cost of Bugs
When a bug is caught while developing a feature, the team loses a few seconds (or minutes in a slow-to-compile project).
However, if a bug is caught in QA, the team loses an hour or more pretty consistently, due to:
- Build time
- Environment spin-up time/deploy time
- Task switching by multiple parties
- Time spent making sure it’s not an environment/setup issue
- Time spent writing up a bug case/steps to reproduce/etc.
And, regardless of who finds the bug, an engineer is who will be fixing it.
On any given feature, at the very least, the happy path and the documented states should be fully-tested and made solidly-working during dev time before QA gets involved. This frees up QA to do exploratory testing, more in-depth test/build/environment automation, general process improvements, regression interpretation, and all the more subtle things that ensure a quality product.
Case verification should be straightforward and nearly always succeed. Contrary to popular belief, QA’s verification of a case isn’t a test for whether the code does what the developer intended, it’s a confirmation that everyone’s interpretation of the requirements is successfully aligned and that no individual’s biases hid a likely scenario.
Each developer should be willing to bet money that the code does what they intend it to do when they mark it as “ready to test.”
There are several ways to gain this confidence, each with their own benefits/drawbacks.
Unit Tests are largely considered the best option as they provide confidence for the next dev in that area of the code (or yourself in a week or seven), but they can lead to unnecessary concretion for experimental/temporary features.
Integration Tests don’t lag far behind but extra care should be taken so as not to “randomly” fail or wildly extend build times.
If all else fails, a Manual Test will do. Make sure to include a note about what you’ve done to ensure accuracy on the relevant ticket. Writing this note often reveals a test case you may not have considered.
As a further time-saving measure, it really helps QA to know any relevant URLs, deploy steps, or flags to turn on. You’ll have the context in your head already, and noting it on the ticket can save several communication round trips and reduce context-switching time in the event of required changes. This will also help to prevent environmental issues from kicking back a case.
Fair disclaimer, this isn’t even my idea! Most people tend to cite Uncle Bob Martin, author of The Clean Coder, for coming up with this concept. Here’s a relevant blog post if you’re interested in reading more!