Q3 of 38 · Test design
Explain boundary value analysis with a simple example.
Short answer
Short answer: Boundary value analysis tests at the edges of equivalence classes — values just below, exactly at, and just above the boundaries. It catches off-by-one bugs that cluster at boundaries. For an age field accepting 18-65, BVA tests 17, 18, 65, and 66.
Detail
BVA is built on the empirical observation that off-by-one bugs cluster at boundaries. Developers write >= 18 when they meant > 17, or <= 65 when they meant < 66. The body of the valid range almost never hides bugs; the edges do.
The technique: identify each boundary in the input space, test the value just below, exactly at, and just above each boundary. Pair with equivalence partitioning to also cover the body of each class.
Worked example for an age field accepting 18-65 (inclusive):
| Value | Class | Why test |
|---|---|---|
| 17 | Below valid | Lower-boundary minus one |
| 18 | Valid | Lower-boundary exactly |
| 19 | Valid | Lower-boundary plus one |
| 65 | Valid | Upper-boundary exactly |
| 66 | Above valid | Upper-boundary plus one |
| 35 | Valid | Body of the class (EP) |
Six tests catch every common boundary bug for this field.
The technique extends beyond numbers: string length (0 chars, 1 char, max-1, max, max+1), dates (midnight on the day before / of / after a deadline; year boundaries; February 28/29), collections (empty array, 1 item, max, max+1).
What BVA doesn't help with: combinatorial inputs (use pairwise), state-dependent boundaries (use state transition), domains with no clear boundaries (use exploratory or property-based testing).
// EXAMPLE
age.test.ts
import { test, expect, describe } from 'vitest';
import { validateAge } from './age';
describe('validateAge — BVA on 18..65 inclusive', () => {
test.each([
[17, false], // just below lower
[18, true], // on lower
[19, true], // just above lower
[65, true], // on upper
[66, false], // just above upper
])('age %i → valid=%s', (age, expected) => {
expect(validateAge(age).ok).toBe(expected);
});
});