Skip to content
fx-blog

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.

Harry4 min readBeginner
  • Intelligence
  • Verification
MarkdownSave

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

TL;DR Testing with whatever values come to mind costs you the bug at the edge and a coverage claim nobody can check. Test design techniques pick the few values most likely to fail: partitions, boundaries and a decision table for rules that combine. A timed exploratory session finds what no rule mentions, and a precise bug report gets it fixed.

Do this: Take one rule with a number in it from your own product and write its three boundary tests: just below, on, and just above the limit.

Part 1 left the ShopLite checkout spec untested: six rules and millions of possible inputs. Which values for SAVE10 are 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:

  1. The QA Skills Path for 2026: What to Learn, in What Order
  2. Test Design Techniques: Pick the Few Tests That Find Bugs (you are here)
  3. Test Below the UI: Your First API Tests in Python
  4. Why Your UI Tests Flake, and the Fix for Web and Mobile
  5. Green Tests, Broken Checkout: The Checks Functional Tests Miss
  6. Quality Gates in CI: Make Your Tests Block a Bad Merge
  7. AI in Testing: Use It Without Trusting It, and Test AI Features

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 SAVE10 needs a subtotal of at least €50.00. Money moves in steps of €0.01, so three values cover the edge:

Subtotal Expected
€49.99 Code rejected: "Minimum order €50.00"
€50.00 10% off → €45.00
€50.01 10% off → €45.01 (rounding 45.009 up)

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:

T1 T2 T3 T4
Code SAVE10 SAVE10 FREESHIP SAVE10 + FREESHIP
Subtotal ≥ €50 Y N – Y
Result 10% off "Minimum order" Free shipping ?

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:

mermaid
flowchart LR
  C[Charter: explore X with Y to discover Z] --> S[60 to 90 minutes]
  S --> N[Timestamped notes]
  N --> D[10 to 15 minute debrief]
  D -->|next charter| C
  N -->|bug| R[Bug report]
textSession notes: Explore cart changes after a code is applied
14:03  Cart: 2 × Mug (€30.00) = €60.00. Applied SAVE10 → €54.00 ✓
14:07  Reduced to 1 Mug (€30.00). Total shows €27.00. Discount still applied below €50 ❓
14:09  Refreshed page → still €27.00. Paid with test card → order #A-1042 total €27.00 🐞
14:15  Same steps via API (PATCH /cart/lines) → API removes code ✓. UI-only problem?

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:

  • Bad: Discount broken
  • Good: Checkout: SAVE10 stays applied after cart drops below €50 minimum

Then: 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

textA charter for your next session
Explore <one feature> with <inputs, tools or tricks>
to discover <the kind of problem you're after>.
Time box: 60 minutes. Notes with timestamps. Debrief: 10 minutes.

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

textPaste into your AI
Read the post "Test Design Techniques: Pick the Few Tests That Find Bugs".
1. I'll paste one rule from my product. List its partitions and 3-value boundaries.
2. Build a decision table for any rules that combine, and mark the cells the rule doesn't answer.
3. Write one exploratory charter for it, in the explore-with-to-discover form.

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

  1. QA Skills Path: Test Design Techniques
  2. QA Skills Path: Exploratory Testing and Bug Reports
  3. Elisabeth Hendrickson, Explore It! (Pragmatic Bookshelf)

Was this useful?

Only you and the owner see your answer and rating. Send private feedback

Enjoyed it? Support fx-blog with a coffee.

Comments

Oldest first

No comments yet. Start the conversation.

You sign in first; what you typed stays here. · 0 / 2,000