The short answer is this: you design test cases that actually catch bugs when you stop improvising inputs and start applying techniques that cover the risk with a handful of well-chosen cases. The three that pay off most are equivalence classes, boundary value analysis, and decision tables. They do not test everything, because testing everything is impossible; they test what matters, and they do it in a way anyone can repeat.
Every tester eventually runs into the same wall: the possible combinations of a simple form already outnumber anything you could run in a lifetime. An age field that accepts numbers from 0 to 120, a country field with 200 options, a discount that hinges on three conditions. Multiply it out and you get an absurd number. Testing case by case is not thoroughness, it is surrendering to brute force. And brute force runs out before the bugs do.
01 · the problemInfinite possible tests, finite time
The starting point of test design is accepting an uncomfortable truth that the ISTQB lists among its fundamental principles: exhaustive testing is impossible, except in trivial cases. You cannot exercise every input or every combination. So the useful question is never "how do I test everything?" but "what small subset of tests gives me the most confidence for the least effort?".
This is where intuition falls short. An experienced tester "smells" where the risk is, but that instinct is neither documented nor teachable. Design techniques do the opposite: they turn that nose into a procedure. Hand the same rules to two people and you get almost the same cases. That is what reproducible means, and it is what separates a professional suite from a list of hunches.
Testing everything is impossible. Choosing well what to test is the entire skill.
The techniques that follow are black box: you design the cases by looking at what the system should do, not how it is written inside. You do not need to read the code. You need to understand the specification and know where errors tend to hide.
02 · classes and limitsPartition the problem and attack the edges
The first technique is equivalence class partitioning. The idea is simple and powerful: you group the possible inputs into classes where the system should behave the same, and you test a single representative of each class. If an age field accepts 0 to 120, you have three obvious classes: values below (invalid), the valid ones, and values above (invalid). There is no need to test 43 and 44 and 45; if the system handles 44 well, it will handle all of its classmates well. One case per class, not a hundred.
The second technique fixes the blind spot of the first. Bugs are not spread evenly: they cluster at the edges. A programmer writes < where <= was needed, and the error surfaces only right at the limit. That is why boundary value analysis tests the extremes of each class and their immediate neighbors. For the range 0 to 120, you do not test some arbitrary number in the middle: you test -1, 0, and 1 at the lower edge, and 119, 120, and 121 at the upper one. That is where software breaks.
Equivalence classes without boundary values let the most common programming bug slip through: the off-by-one error. Boundary values without classes make you test the edges of everything, with no criterion. Together they balance out: classes cut the number of cases, boundaries raise the odds that each case catches something. The ISTQB teaches them paired for exactly this reason.
03 · the logicDecision tables for business rules
Classes and limits work beautifully when each input is tested on its own. But a lot of software is not like that: the output depends on combinations of conditions. "If the customer is premium and the cart tops 50 euros and it is their first purchase, apply a double discount." There, testing each condition in isolation is not enough, because the bug lives in the interaction between them.
The right technique is the decision table. You list the input conditions on top, the actions or results below, and each column is a possible combination with its expected result. With three binary conditions you get eight combinations; the table forces you to look at all of them and to decide, specification in hand, what should happen in each. The revealing part is what almost always occurs: as you fill in the table you uncover combinations no one had thought about and for which the specification says nothing. That gap is a bug before you write a single test.
When the combinatorial explosion is enormous, you do not test them all. That is where variants like pairwise testing come in, cutting hundreds of combinations down to a few dozen with almost no loss in defect coverage. The principle is the same one running through the whole article: do not cover every combination, cover the risk with the fewest cases.
The table does not just generate cases: it shows you the rules nobody wrote down.
04 · the criterionWhen to use each technique and how to document it
No technique is the good one in the abstract; each answers a form of risk. The practical guide is this: if the field has ranges or sets of values, use equivalence classes with boundary values. If the result depends on the combination of several conditions, use a decision table. If the behavior depends on the order of things or on the state of the system, you are missing a fourth technique, state transition, which deserves its own article.
And there is one rule that wraps around them all: a test case without an expected result defined beforehand is not a test case, it is an exploration. The power of these techniques is that the expected result comes from the specification, not from looking at what the system did and calling it good. Without that prior oracle, you are not testing: you are confirming your own bias.
All of this connects to something bigger than bug hunting. The ISO/IEC 25010 standard defines software quality through attributes such as functional correctness, and case design techniques are, literally, the way to provide evidence that this attribute is met. It is not bureaucracy: it is the difference between claiming "this works" and being able to show with which cases, chosen by which criterion, you verified it. The ISTQB places these techniques at the heart of a tester's training precisely for this reason: they are the bridge between intuition and method.
So next time you feel the vertigo of infinite possible tests, do not start typing random inputs. Ask first: are these ranges, combinations, or states? The answer tells you which technique to pull from the box, and all at once the problem stops being infinite and becomes a short list, ordered and, above all, repeatable.
Sources
- ISTQB (International Software Testing Qualifications Board). Certified Tester Foundation Level (CTFL) Syllabus. Capítulo sobre técnicas de prueba de caja negra: partición de equivalencia, análisis de valores límite y tablas de decisión; principio de imposibilidad de la prueba exhaustiva. istqb.org.
- Myers, G. J., Sandler, C. & Badgett, T. (2011). The Art of Software Testing (3.ª ed.). John Wiley & Sons. (Obra clásica que formaliza el análisis de valores límite y la partición en clases de equivalencia.)
- ISO/IEC 25010:2011. Systems and software engineering. Systems and software Quality Requirements and Evaluation (SQuaRE). System and software quality models. International Organization for Standardization. (Modelo de calidad; atributo de idoneidad/corrección funcional.)
- ISO/IEC/IEEE 29119-4. Software and systems engineering. Software testing. Part 4: Test techniques. (Estándar internacional que cataloga las técnicas de diseño de pruebas basadas en especificación.)