QA

Test design techniques: covering more with fewer cases

Testing every possible input is impossible — a simple integer field already has billions of values. A QA's maturity shows precisely here: in choosing the smallest set of cases that finds the largest number of defects. That is what black-box test design techniques are for. They are classics (straight from ISTQB) and are used all the time, even when the QA doesn't realize they're using them.

The map of techniques

How do you derive test cases without testing everything?
        │
        ├── Inputs with ranges/groups
        │      ├── Equivalence partitioning  → 1 value per group
        │      └── Boundary value analysis   → the edges of the groups
        │
        ├── Combination of conditions
        │      └── Decision table            → business rules "if A and B then..."
        │
        └── Behavior that depends on the past
               └── State transition          → statuses, flows, state machines

1. Equivalence partitioning

The idea: if a group of inputs is treated the same way by the system, testing one value from the group is equivalent to testing all of them. You split the domain into classes (valid and invalid) and pick one representative from each.

Example — an age field that accepts 18 to 65:

  • Invalid (below): any value < 18 → e.g. 10
  • Valid: 18 to 65 → e.g. 30
  • Invalid (above): > 65 → e.g. 80

Three cases cover the behavior of the whole field. Testing 30, 31 and 32 would be a waste — they all fall in the same partition.

2. Boundary value analysis

Bugs love edges. A > that should have been >=, the "off-by-one", the limit nobody tested. This technique complements partitioning by testing exactly the extremes of each range. For the age field (18–65), the values that matter are:

     17   |   18   ...   65   |   66
   invalid |  valid (18 to 65) |  invalid
       ^        ^          ^         ^
     edge     first       last      edge
   rejects   accepts    accepts   rejects

The cases: 17 (rejects), 18 (accepts), 65 (accepts), 66 (rejects). This is where most validation defects hide — and it's one of the first things a technical interviewer asks: "how would you test this field?".

3. Decision table

When the rule depends on the combination of several conditions, listing everything in your head fails. The decision table maps each combination of conditions to the expected action — and exposes rules nobody had thought of.

Example — a discount that depends on being a VIP customer and the purchase exceeding R$ 100:

Condition / RuleR1R2R3R4
Is a VIP customer?YesYesNoNo
Purchase > R$ 100?YesNoYesNo
Discount applied20%10%10%0%

Each column is a test case. The technique guarantees no combination is forgotten — including R4, the "nothing happens" case, which tends to be left out of happy-path tests.

4. State transition

Some behaviors depend on history, not just the current input. An order can go from Created → Paid → Shipped, but never from Created → Shipped. Here you model a state machine and test both the valid and the forbidden transitions:

   [Created] ──pay──► [Paid] ──dispatch──► [Shipped] ──deliver──► [Delivered]
       │
       └──cancel──► [Cancelled]

   Invalid transitions to test:
     • Created ──dispatch──►  (must be blocked)
     • Shipped ──pay──►       (must be blocked)
     • Delivered ──cancel──►  (must be blocked)

The payoff is in the invalid transitions: that's where the "I managed to cancel an order that was already delivered" bugs live. Testing only the happy path leaves that hole open.

Combining is the rule, not picking one

In practice these techniques add up. A single sign-up form might call for partitioning + boundary values on numeric fields, a decision table for the "who can sign up" rule, and state transition for the account activation flow. The right question is never "which technique should I use?", but "which conditions of this requirement does each technique help me cover?".

Testing well isn't testing a lot — it's testing the right things. These techniques are the reasoning that turns "I clicked around and it looks fine" into defensible coverage.

Conclusion

Equivalence partitioning and boundary values attack inputs; decision tables attack combinations; state transition attacks behavior that depends on the past. Together, they give the QA a solid answer to the most frequent question in any technical interview — "why did you choose these cases and not others?" — and, more importantly, they find defects that improvised testing never would.

Read also

Back to the blog