TEST DESIGN
Boundary Value Analysis.
Black-Box A black-box test design technique that focuses on the values at and just beyond the edges of input ranges — the points where off-by-one bugs are almost always hiding.
What it is
Boundary Value Analysis is a technique for generating the minimum set of test values that is statistically most likely to expose off-by-one and fence-post errors. Instead of testing random values inside a valid range, BVA selects exactly six values per range boundary: one below the minimum, the minimum itself, one above the minimum, one below the maximum, the maximum itself, and one above the maximum. The rationale is empirical: the large majority of range-validation defects manifest at or within one unit of the boundary, not in the middle of the range. BVA gives you maximum defect exposure for minimum test count.
When to use it
When to use
- Any numeric input with a declared min and max (age fields, price inputs, item counts, year selectors)
- String length constraints (username 3–20 chars, password 8–64 chars, bio max 500 chars)
- Date range inputs where business rules define earliest and latest allowed values
- File size limits (upload capped at 10 MB — test 9.99 MB, 10.00 MB, 10.01 MB)
- Percentage and ratio fields (discount 0–100%, tax rate 0–99.99%)
- API request parameters that are validated against a numeric range
When NOT to use
- Boolean fields (true/false) — there are no boundaries, use Equivalence Partitioning instead
- Unordered categorical fields (dropdown: Red / Green / Blue) — no meaningful boundary exists
- Free-text fields without a length constraint — the range is unbounded
- When the field's constraint is complex business logic rather than a simple numeric range — use Decision Table Testing instead
How it works
For any range [min, max], BVA derives six test values: min−1 (just invalid), min (just valid), min+1 (valid interior), max−1 (valid interior), max (just valid), max+1 (just invalid). The boundary on both sides should be tested because off-by-one bugs can appear at either end — a developer who wrote > instead of >= will pass max but reject min. The worked example below uses an age field that accepts 18–65.
Registration form — age field must be 18–65 (inclusive)
| Test value | Position | Expected result | Result |
|---|---|---|---|
| 17 | min − 1 (below minimum) | Rejected — too young | Reject |
| 18 | min (minimum boundary) | Accepted | Accept |
| 19 | min + 1 (just inside minimum) | Accepted | Accept |
| 64 | max − 1 (just inside maximum) | Accepted | Accept |
| 65 | max (maximum boundary) | Accepted | Accept |
| 66 | max + 1 (above maximum) | Rejected — too old | Reject |
⚠ Only 6 values needed to cover all 4 boundary points. The middle of the range (e.g. 40) adds negligible defect-detection value.
Step by step
Identify every range-constrained input
Read the specification or field-level UI hints for declared min/max. If the spec doesn't state them, ask — an undocumented boundary is a requirement gap, not a test gap.
Determine the type and unit of the boundary
Is the boundary an integer, a float, a string length, a file size in bytes, or a date? The unit determines what 'min−1' and 'max+1' mean: for integers it's ±1; for floats it's the smallest representable step (e.g. ±0.01 for 2dp fields); for dates it's ±1 day.
Generate the six test values
For each boundary: min−1, min, min+1, max−1, max, max+1. For a field with only a minimum (no declared max), test min−1 and min only. For a field with only a maximum, test max and max+1.
Determine the expected result for each value
Boundary-crossing values (min−1 and max+1) must be rejected; boundary values (min and max) and interior values (min+1 and max−1) must be accepted. Note exactly what error message or API response code is expected for the rejected values.
Execute and assert
Enter each value into the field and assert: (a) valid values are accepted and processing continues, (b) invalid values are rejected with the correct error message, (c) the error targets the correct field. Use the Boundary Value Generator utility to produce the values automatically.
Pitfalls & what it misses
Treating inclusive and exclusive boundaries as equivalent
If the spec says 'age must be greater than 18' (exclusive), the boundary is 18 = rejected, 19 = accepted — not 18 = accepted. Misreading inclusive vs. exclusive boundaries is the most common BVA mistake. Always check whether min and max themselves are valid.
Forgetting decimal precision on float fields
A price field that allows values up to £99.99 should be tested at £99.98 (max−0.01), £99.99 (max), and £100.00 (max+0.01). Testing at £100 (max+1) misses the £99.995 rounding edge case if the server rounds to 2dp differently.
BVA doesn't catch combinations of invalid inputs
BVA tests one field's range in isolation. It won't catch a bug that only appears when two out-of-range values are submitted together — use Equivalence Partitioning or Pairwise Testing for multi-field interaction defects.
Skipping min−1 or max+1 because they 'obviously' fail
The point of the invalid boundary values is not to confirm they're rejected — it's to confirm the correct error is returned and the system doesn't crash or behave unexpectedly (e.g. wrapping around, silently clamping, or storing the invalid value).
Paired utility
// Related resources