Test Design Techniques: Pick the Few Tests That Find Bugs
Testing with whatever values come to mind misses the bug at the edge and leaves a coverage claim nobody can check. Pick values with partitions, boundaries and decision tables, explore in timed sessions, and write bug reports a developer can reproduce.
Key takeaways
- Equivalence partitioning picks one value per group the system treats the same way; boundary value analysis then tests the edges of each group.
- For a rule like a €50.00 minimum, the three values €49.99, €50.00 and €50.01 test the edge where a developer writes < instead of <=.
- Test invalid values one at a time, or you can't tell which check rejected the input.
- A decision table's unanswered cells are questions for the product owner, and are often its most useful output.
- An exploratory session has a charter, a 60 to 90 minute time box, notes taken during the session and a debrief.
- A bug report that gets fixed names where, what and when in the title, gives exact numbers, and says what was already ruled out.
Contents
FAQ
What is the difference between equivalence partitioning and boundary value analysis?
Equivalence partitioning splits inputs into groups that should behave the same and tests one value from each. Boundary value analysis tests the values at and around the edges of those groups, where off-by-one mistakes happen.
Is exploratory testing just clicking around?
No. A session has a written charter that says what to explore, with what, to discover what; a fixed time box; notes taken as you go; and a debrief afterwards. That makes it reviewable.
Who sets the priority of a bug?
The tester proposes the severity, which is how bad the effect is. The product owner or team decides the priority, which is how soon it must be fixed.
Sources
Only you and the owner see your answer and rating. Send private feedback
Enjoyed it? Support fx-blog with a coffee.
Related posts
AI in Testing: Use It Without Trusting It, and Test AI Features
Trusting AI output gives you tests that can't fail and an assistant that invents policy. Review every AI-written test by breaking the feature on purpose, keep agents out of the gate, and test AI features with eval sets run in CI.
Quality Gates in CI: Make Your Tests Block a Bad Merge
Tests that run only when someone remembers put the gate in a person. Run them in four CI tiers that each block the next, keep the commit gate under ten minutes, give every run fresh data, and quarantine flaky tests the same day.
Green Tests, Broken Checkout: The Checks Functional Tests Miss
A green functional suite can't see a renamed field, a slow peak, an open security hole or a form a keyboard can't finish. Add a Pact contract, a k6 test against an SLO, a ZAP baseline scan, and axe plus a keyboard pass.
Comments
Oldest firstNo comments yet. Start the conversation.
Part 1 left the ShopLite checkout spec untested: six rules and millions of possible inputs. Which values for
SAVE10are worth a test, and what happens to the rule the spec forgot?Start with a mistake that looks like diligence. Five valid quantities, 1, 3, 5, 7 and 9, find fewer bugs than four values at the edges: 0, 1, 10 and 11.
The QA Skills Path, in seven parts:
Pick the groups, then the edges
Equivalence partitioning splits an input into groups the system should treat the same way; one value per group is enough. Boundary value analysis then tests the edges of each group, because that is where a developer writes
<instead of<=.Rule R3 says
SAVE10needs a subtotal of at least €50.00. Money moves in steps of €0.01, so three values cover the edge:The same move works on every number in the spec: quantity 0, 1, 2 and 9, 10, 11; code lengths 3, 4, 5 and 11, 12, 13.
A table finds the rule nobody wrote
When an outcome depends on a combination, list every combination. Codes R3 and R4 interact, so:
The spec says the codes can't be combined, but not which error T4 shows, or whether the first code stays. That question mark is the most useful cell: take it to the product owner before the code is built.
Two more techniques work the same way. State-transition testing checks the moves that must be refused, such as a payment webhook arriving after a cancel. Pairwise testing covers payment, code, device and customer type in about 9 or 10 tests instead of 36.
Explore what no rule mentions
Designed tests only check what someone thought of. An exploratory session finds the rest, and it has a shape:
No row in the boundary table changes the cart after the code is in. The charter did, and found a bug in four minutes.
Write the bug so it gets fixed
A bug nobody understands stays open. The title says where, what and when:
Discount brokenCheckout: SAVE10 stays applied after cart drops below €50 minimumThen: environment, preconditions, only the steps needed, the expected result with its source (rule R3), the actual result in exact numbers, frequency and evidence. The repo's BUG-311 adds one more line, what was already ruled out: the API recalculates correctly when called directly, so the fault looks like stale state in the page. Severity is your proposal; priority is the product owner's call.
Try it
You now have a short list of ShopLite tests you can defend, and BUG-311 written up. But look at the 14:15 line again: the API removed the code, and only the page got it wrong. You checked that once, by hand. How do you test the API itself, every time, without a browser? Part 3, Test Below the UI: Your First API Tests in Python, writes those tests in code.
Read this with your AI