Skip to content
SDETRole
SDETRole

Lesson 4 of 11 · Software Testing Fundamentals

Test Case Design Techniques

Equivalence partitioning, boundary value analysis, decision tables, state transitions, pairwise and experience-based techniques, with worked examples you can reuse.

beginner 9 min read Updated

You will learn to

  • Derive test cases with equivalence partitioning and boundary value analysis
  • Model business rules as decision tables and workflows as state transition diagrams
  • Reduce combinations with pairwise testing
  • Combine black-box techniques with error guessing and exploratory testing

Prerequisites

  • Introduction to Software Testing
  • STLC: The Software Testing Life Cycle

Because exhaustive testing is impossible, every tester faces the same question: out of the effectively infinite inputs and paths, which handful of tests should I actually run? Test design techniques are systematic answers to that question. They help you pick tests that are most likely to reveal defects, explain why you chose them, and show what you deliberately left out.

These techniques appear in the ISTQB Foundation syllabus and in almost every QA interview. More importantly, they are the difference between “I tried a few things” and a test set you can defend.

Three families of techniques

Family Based on Examples
Black-box (specification-based) Requirements and behaviour, without looking at code Equivalence partitioning, boundary value analysis, decision tables, state transition, pairwise
White-box (structure-based) The code’s internal structure Statement coverage, branch coverage
Experience-based The tester’s knowledge and intuition Error guessing, exploratory testing, checklists

This lesson focuses on black-box and experience-based techniques, which you can apply from day one without access to the code.

Equivalence partitioning

Idea: divide inputs into groups (partitions) that the system should treat the same way. If one value in a partition works, the others should too, so you test one value per partition.

Example: an age field for an insurance quote accepts ages 18 to 65 inclusive. Ages must be whole numbers.

Partition Range Valid? Representative value
Below minimum 17 and below Invalid 10
Accepted 18 to 65 Valid 40
Above maximum 66 and above Invalid 80
Not a whole number e.g. 30.5 Invalid 30.5
Not a number e.g. “abc” Invalid abc
Empty blank Invalid (empty)

Six tests instead of hundreds, with each test standing in for a whole class of inputs.

Rules of thumb:

  • Partition outputs too, not only inputs. If quotes fall into price bands, each band is a partition.
  • Test invalid partitions one at a time. If you send an invalid age and an invalid email together, you cannot tell which one the error message is about; one may mask the other.

Boundary value analysis

Idea: defects cluster at the edges of partitions, because that is where developers write comparisons like > versus >=. Boundary value analysis (BVA) tests values on and around each boundary.

There are two common variants:

  • Two-value BVA: for each boundary, test the boundary value and its nearest neighbour in the adjacent partition.
  • Three-value BVA: test the boundary value and the values just below and just above it.

For the 18 to 65 age rule:

Boundary Two-value BVA Three-value BVA
Lower (18) 17, 18 17, 18, 19
Upper (65) 65, 66 64, 65, 66

Why this catches bugs: if the developer wrote age > 18 instead of age >= 18, only the test with exactly 18 reveals it. A “typical” value like 40 never will.

// The defect that BVA is designed to catch
function isEligible(age) {
  return age > 18 && age <= 65; // bug: 18 should be accepted
}

isEligible(40); // true  - passes, hides the bug
isEligible(18); // false - boundary test exposes it

Boundaries are everywhere once you look: string lengths (password of 7, 8 characters), dates (the day before, on and after an expiry), quantities (0, 1, max stock), file sizes, pagination limits and time-outs. Try the Boundary Value Calculator to generate values for any range.

Decision table testing

Idea: when behaviour depends on combinations of conditions, list every combination in a table with the expected action. This exposes missing and contradictory rules.

Example: a shop’s shipping rules.

  • Members get free shipping.
  • Non-members get free shipping on orders of 50 or more.
  • Express shipping always costs 10, even for members.
Rule R1 R2 R3 R4 R5 R6 R7 R8
Member? Y Y Y Y N N N N
Order 50 or more? Y Y N N Y Y N N
Express? Y N Y N Y N Y N
Shipping cost 10 0 10 0 10 0 ? standard

Building the table surfaces a question the requirements did not answer: R7, a non-member with a small express order. Is it 10, or the standard fee plus 10? That gap is a finding before you have run a single test.

With three yes/no conditions there are 2 × 2 × 2 = 8 combinations. Where some conditions do not affect the outcome, columns can be collapsed (“Express = Y gives 10 regardless of the other two”), which reduces the number of tests while keeping every rule covered.

State transition testing

Idea: when a system behaves differently depending on its current state and the event that occurs, model it as states and transitions, then test the transitions, including invalid ones.

Example: an order lifecycle.

[Created] --pay--> [Paid] --ship--> [Shipped] --deliver--> [Delivered]
    |                 |
  cancel           cancel (refund)
    v                 v
[Cancelled] <---------

A state table makes invalid transitions explicit:

Current state pay ship cancel deliver
Created Paid invalid Cancelled invalid
Paid invalid Shipped Cancelled (refund) invalid
Shipped invalid invalid invalid Delivered
Delivered invalid invalid invalid invalid
Cancelled invalid invalid invalid invalid

Tests to derive:

  • Every valid transition at least once (the simplest coverage level).
  • Invalid transitions: can you ship a cancelled order? Cancel a delivered one? Pay twice? These are frequent sources of serious bugs, especially when the UI hides a button but the API still accepts the request.

Pairwise testing

Idea: many defects are triggered by the interaction of two parameters rather than three or more. Pairwise (all-pairs) testing picks a small set of combinations in which every pair of values appears at least once.

Example: a checkout tested across browser (Chrome, Firefox, Safari), payment (card, PayPal, voucher) and user type (guest, member). All combinations: 3 × 3 × 2 = 18. A pairwise set covers every pair in 9 tests:

# Browser Payment User
1 Chrome Card Guest
2 Chrome PayPal Member
3 Chrome Voucher Guest
4 Firefox Card Member
5 Firefox PayPal Guest
6 Firefox Voucher Member
7 Safari Card Guest
8 Safari PayPal Member
9 Safari Voucher Member

Check: every browser meets every payment once, and every browser and every payment meets both user types at least once. The savings grow quickly with more parameters. Generate sets with the Pairwise Generator.

Experience-based techniques

Formal techniques miss defects that experience catches. Use them alongside, not instead.

  • Error guessing: anticipate likely mistakes from experience. Common targets: empty and whitespace-only input, very long strings, Unicode and emoji in names, leading zeros, time zones and daylight-saving changes, double-clicking submit, browser back after payment, two tabs editing the same record.
  • Checklist-based testing: maintain checklists from past defects and standards (accessibility, security basics, form behaviour).
  • Exploratory testing: simultaneous learning, test design and execution, guided by a charter such as “Explore discount codes with unusual cart contents to discover pricing errors” and time-boxed to an hour or so.

Choosing techniques

If the feature has… Start with
Input ranges and fields Equivalence partitioning + boundary value analysis
Business rules with combined conditions Decision tables
Workflows, statuses, lifecycles State transition testing
Many configuration options or environments Pairwise testing
Unclear specs, new or risky areas Exploratory testing and error guessing

Most real features need two or three techniques together.

Practice exercise

A registration form has these rules:

  • Username: 4 to 16 characters, letters and digits only.
  • Age: whole number, 13 or older.
  • Country: one of US, UK, IN; users from IN under 18 need a parent’s email.

Produce:

  1. Equivalence partitions and boundary values for username length and age.
  2. A decision table for the country/age/parent-email rule.
  3. Three error-guessing tests.

Use the Boundary Value Calculator to check your boundaries and the Test Case Generator to write them up. A good answer separates valid and invalid partitions, includes both sides of every boundary, and finds at least one gap in the rules.

Show a model answer

Username length: partitions are 0 (empty), 1–3 (too short), 4–16 (valid), 17+ (too long). Character partitions: letters and digits (valid), containing a space, symbol or non-ASCII letter (invalid). Boundaries (three-value): 3, 4, 5 and 15, 16, 17.

Age: partitions are below 13 (invalid), 13+ (valid), non-integer, non-numeric, empty. Boundaries: 12, 13, 14. For the IN rule, add 17, 18, 19.

Decision table

Rule R1 R2 R3 R4
Country is IN? Y Y Y N
Age under 18? Y Y N (any)
Parent email given? Y N (any) (any)
Result Accept Reject: parent email required Accept Accept

Gaps found: Is there a maximum age? Is the parent email validated, and can it equal the user’s own email? Is “Ana_1” rejected (underscore) and is “ÁnaBeta” rejected (non-ASCII letter)?

Error guessing

  • Username with leading or trailing spaces, such as “ ana1 “.
  • Username that differs only by case from an existing one (“Ana1” vs “ana1”).
  • Age entered as “013” or “13.0”.

Key takeaways

  • Test design techniques turn an infinite input space into a small, defensible set of tests.
  • Equivalence partitioning picks one value per class; boundary value analysis tests the edges, where comparison bugs live.
  • Decision tables cover combinations of conditions and expose missing rules; state transition testing covers workflows, including invalid transitions.
  • Pairwise testing covers every pair of parameter values with far fewer tests, but not higher-order interactions.
  • Combine formal techniques with error guessing and exploratory testing.

Key terms

Finished this lesson?

Progress is saved in this browser. No account needed.

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →