Imagine an "age" field that accepts numbers from 18 to 60. How many values should you test? All of them in order — 18, 19, 20… 60 — that's 43 checks, and most of them tell you nothing new. Test design is a set of techniques that help you cover the same ground with a few smart test cases instead of dozens of random ones.
The two main techniques every tester should know from day one are equivalence classes (equivalence partitioning) and boundary values (boundary value analysis). They're straightforward and cover a huge portion of the work.
Equivalence classes
The idea: divide all possible values into groups where the program behaves the same way. Then it's enough to check one value from each group — the rest won't reveal anything new.
For the "age from 18 to 60" field there are three groups:
- Less than 18 (for example, 15) — should not be accepted.
- From 18 to 60 (for example, 30) — should be accepted.
- Greater than 60 (for example, 70) — should not be accepted.
There's no need to test 15, 16, and 17 separately: they all fall into the "less than 18" group and the program handles them the same way. One representative is enough. So 43 checks become 3.
Groups aren't only numeric. For a "country" dropdown — is every country its own separate situation? Usually not: the program doesn't care whether it's France or Germany. But "a country is selected" and "no country is selected" are different classes.
Boundary values
Equivalence classes tell you which groups to test. But experience shows that bugs most often live at the boundaries of groups, not in the middle. Developers constantly confuse "greater than" with "greater than or equal to," "up to" with "inclusive." That's why boundaries are tested separately and with extra care.
For "age from 18 to 60" the boundaries are 18 and 60. We check around them:
- 17 — one below the lower boundary, should not be accepted.
- 18 — the lower boundary itself, should be accepted.
- 60 — the upper boundary itself, should be accepted.
- 61 — one above the upper boundary, should not be accepted.
This is where classic bugs get caught: "it accepts 17 even though it shouldn't" or "it doesn't accept 60 even though it should." Values like 19 or 59 in the middle don't need to be tested — the equivalence class covers them.
Together: fewer test cases, more meaning
Both techniques are used as a pair. First you use equivalence classes to map out the groups (one representative each), then you use boundary values to reinforce the check at the edges. For our "age" field the result is roughly six data points: 17, 18, 30, 60, 61, plus something completely invalid (letters, empty).
This is the key insight of test design: more test cases ≠ better. A hundred random checks are worse than six well-chosen ones. A good tester doesn't work through everything in order — they aim precisely where bugs are likely to be.
Don't forget completely "bad" inputs that don't fit into any normal class: an empty field, text instead of a number, a negative number, a huge number, special characters. These are classes too — "invalid input" — and negative test cases for them are required.
Where this applies
You'll apply these two techniques to literally every input field and every condition: order amount, item quantity, name length, date, date range. As soon as you see "accepts values from X to Y" or "no more than N characters" — immediately think: which classes, where are the boundaries? This turns a vague "we need to test this field" into a specific, short list of test cases.
Where beginners stumble:
- Testing many values from one group (18, 19, 20, 21…) and none from the boundary. Lots of effort, little value.
- Forgetting the boundaries — which is exactly where bugs like to hide. Always test the boundary value itself and one step to each side.
- Skipping invalid input. An empty field, letters instead of digits, special characters — that's a separate class where a huge number of bugs live.
What to learn next. Equivalence classes and boundary values work well for a single field. When the result depends on a combination of several conditions, decision tables and pairwise testing come in handy.