Black Box · Specification-Based

Boundary Value Analysis

Test the edges of equivalence partitions. Bugs cluster at boundaries — off-by-one errors, fencepost mistakes, and incorrect comparisons (< vs ≤) almost always appear at the exact limit.

Junior Senior ISTQB CTFL v4.0 — 4.2.2

1 The Hook

An ANZ online savings product offers a bonus interest rate when the monthly balance stays at $1,000 or above. A team builds the feature and tests it with a tidy round figure: $5,000 in the account, bonus applied, looks great. Ship it.

A month later a customer complains. They held exactly $1,000 all month and got no bonus. The developer had coded the check as balance > 1000 instead of balance >= 1000 — an off-by-one slip. Every customer sitting on precisely the threshold was quietly short-changed. The test with $5,000 could never have caught it, because $5,000 is nowhere near the edge where the bug lives.

This is the pattern behind a huge share of real defects: the logic is right in the middle of the range and wrong at the exact limit. A value picked from the comfortable middle of a partition tells you nothing about the boundary. The bug was always going to be at $1,000, $999, or $1,001 — and those were the three values nobody tested.

2 The Rule

Defects cluster at the edges of a range, not in the middle — so for every boundary, test the value on the boundary and the value just across it (2-value), or the value below, on, and above it (3-value).

3 The Analogy

Analogy

The height sign at a theme-park ride.

A ride at Rainbow's End has a sign: "You must be 120 cm to ride." The interesting arguments never happen with a kid who is obviously tall or obviously tiny — they happen with the child measured at exactly 120 cm, or 119, or 121. That is where the rule is tested in the real world: right at the line. Does "120 cm to ride" mean 120 gets on, or 120 is too short? The sign's wording (the spec) decides, and that exact point is where staff get it wrong.

Boundary value analysis is standing at the height sign and measuring the three kids right around the line, instead of waving through the obviously-tall ones. The edge is where the rule either holds or breaks.

What it is

Boundary Value Analysis (BVA) is an extension of Equivalence Partitioning. Once you have your partitions, instead of picking a value in the middle, you test the values at and around the boundary between partitions.

Why boundaries? Developers tend to make off-by-one errors. A spec that says "accept 18–65" might be coded as > 18 instead of >= 18 — a bug that only appears at exactly 18.

2-value BVA (ISTQB standard)

For each boundary, test two values: the boundary itself, and the value just beyond it.

  • For a range 18–65: test 18 (in), 17 (out), 65 (in), 66 (out).

3-value BVA (robust)

Test three values at each boundary: the value just below, the boundary itself, and the value just above.

  • At lower boundary (18): test 17, 18, 19
  • At upper boundary (65): test 64, 65, 66

3-value BVA gives stronger coverage but doubles your test count. Use it when the boundary logic is critical or complex.

Real-world NZ Example: KiwiSaver Eligibility

In New Zealand, to join KiwiSaver independently (without legal guardian consent), you must be 18. You can begin withdrawing your savings at 65. Using 2-value BVA, your test cases are:

  • 17: Invalid (just below independent age)
  • 18: Valid (minimum independent age)
  • 64: Valid (just below withdrawal age)
  • 65: Valid (minimum withdrawal age)
  • 66: Valid (above withdrawal age — still eligible to contribute, but state contribution stops)

Worked example

Password length field: minimum 8 characters, maximum 20 characters.

Password length — 2-value BVA test cases
ValueLengthBoundary?Expected
"passwor"7Just below minRejected
"password"8Minimum boundaryAccepted
"12345678901234567890"20Maximum boundaryAccepted
"123456789012345678901"21Just above maxRejected

Combined with EP: BVA gives you boundary tests; EP gives you mid-range tests. Together they cover: one value per valid partition (EP), the boundaries of each partition (BVA), and one representative invalid value per invalid partition (EP). This is standard practice at junior level and above.

ISTQB mapping

ISTQB CTFL v4.0 reference
Syllabus refTopicLevel
4.2.2Boundary Value AnalysisCTFL Foundation
FL-4.2.2 K3Apply 2-value BVA to derive test casesFoundation LO
FL-4.2.2 K3Apply 3-value BVA to derive test casesFoundation LO

Common mistakes

  • Forgetting the "just outside" value — testing only the boundary itself misses off-by-one errors.
  • Mixing BVA and EP carelessly — BVA tests the boundary; EP tests the middle. Don't conflate them.
  • Non-numeric boundaries — BVA applies to anything ordered: dates, string lengths, list sizes, file sizes, priority levels.
  • Inclusive vs exclusive confusion — always check whether the spec says "<" or "≤" before choosing your boundary values.

4 Now You Try

Three graded exercises — spot, fix, then build. Write your answer, run it for AI feedback, then compare to the model answer.

🔍 Exercise 1 of 3 — Spot: name the boundary values

A Waka Kotahi heavy-vehicle permit form accepts a gross vehicle mass from 3,500 kg to 44,000 kg (inclusive). Using 2-value BVA, list the boundary test values and the expected result (accept/reject) for each. Then state which values 3-value BVA would add.

Show model answer
2-value BVA for the range 3,500–44,000 kg:
- 3,499 kg — Reject (just below lower boundary)
- 3,500 kg — Accept (lower boundary, inclusive)
- 44,000 kg — Accept (upper boundary, inclusive)
- 44,001 kg — Reject (just above upper boundary)

3-value BVA adds the value just inside each boundary:
- 3,501 kg — Accept (just above lower boundary)
- 43,999 kg — Accept (just below upper boundary)

The whole point is the inclusive boundaries: 3,500 and 44,000 must be ACCEPTED. The classic bug is coding > 3500 instead of >= 3500, which would wrongly reject a vehicle at exactly 3,500 kg.
🔧 Exercise 2 of 3 — Fix: repair a flawed BVA set

A tester wrote the BVA set below for a KiwiSaver contribution-rate field (whole percentages 3 to 10 inclusive). It is wrong: it tests middles instead of edges, misses a boundary, and gets one expected result wrong. Rewrite it as a correct 2-value BVA set.

Flawed set:
5 — Accept
3 — Reject
7 — Accept
11 — Reject

Rewrite as correct 2-value BVA:

Show model answer
Correct 2-value BVA for rates 3–10 inclusive:
- 2 — Reject (just below lower boundary)
- 3 — Accept (lower boundary)
- 10 — Accept (upper boundary)
- 11 — Reject (just above upper boundary)

What was wrong with the original:
- Tested middles, not edges: 5 and 7 are mid-range values — that is equivalence partitioning, not BVA. BVA wants the values at and just outside the boundaries.
- Wrong expected result: 3 is the lower boundary and is valid, so it should ACCEPT, not reject.
- Missing boundary: nothing tested 2 (just below min) or 10 (the upper boundary itself). Only 11 was on the upper side.
🏗️ Exercise 3 of 3 — Build: a 3-value BVA set for a date field

An IRD tax-return portal accepts a return for the 2024–25 tax year: valid filing dates run from 1 April 2025 to 7 July 2025 (inclusive). Design a full 3-value BVA set of test dates with the expected result for each. Remember boundaries apply to dates, not just numbers.

Show model answer
3-value BVA for the date range 1 Apr 2025 – 7 Jul 2025 inclusive:

Lower boundary (1 Apr 2025):
- 31 Mar 2025 — Reject (just below)
- 1 Apr 2025 — Accept (boundary, inclusive)
- 2 Apr 2025 — Accept (just above)

Upper boundary (7 Jul 2025):
- 6 Jul 2025 — Accept (just below)
- 7 Jul 2025 — Accept (boundary, inclusive)
- 8 Jul 2025 — Reject (just above)

Six test dates. The "just below" date at the lower edge is 31 March because March has 31 days — date boundaries are where off-by-one and month-length bugs hide. A senior would also flag that both boundary dates must be accepted (inclusive), and would test a leap-day or end-of-month edge if the range crossed one.

Self-Check

Click each question to reveal the answer.

Q1: Why does a test value picked from the middle of a valid range rarely catch boundary bugs?

Boundary defects — off-by-one errors, < vs ≤ mistakes — only change behaviour at the exact limit. A mid-range value behaves identically whether the code says > or ≥, so it cannot expose the slip. You have to test at and around the edge.

Q2: For an inclusive range 8 to 20, what four values does 2-value BVA test, and what are the expected results?

7 (reject, just below min), 8 (accept, lower boundary), 20 (accept, upper boundary), 21 (reject, just above max). The two boundary values themselves must be accepted because the range is inclusive.

Q3: What two extra values does 3-value BVA add at each boundary, and when is it worth the cost?

It adds the value just inside each boundary (e.g. 9 just above the lower edge, 19 just below the upper edge), so each boundary is tested below, on, and above. Use it when the boundary logic is critical or complex; it roughly doubles the test count.

Q4: Does BVA apply only to numbers?

No — it applies to anything ordered: dates, string lengths, list sizes, file sizes, priority levels. A date field has boundaries (first and last valid date) just as a numeric range does, and month-length and leap-day edges make dates especially bug-prone.

Q5: Before choosing your boundary values, what must you check in the specification?

Whether each limit is inclusive or exclusive — "<" versus "≤". The wording decides whether the boundary value itself should be accepted or rejected, and getting that wrong means your expected results are wrong even if your values are right.

Always pair with Equivalence Partitioning — EP defines the partitions, BVA tests their edges.

When multiple input boundaries interact, consider Decision Table Testing or pairwise combinatorial testing.

NZ example — KiwiSaver contribution rates

KiwiSaver employee contribution rates have defined thresholds: 3%, 4%, 6%, 8%, 10%. A contribution rate field that accepts values from 3 to 10 (as a percentage, integers only) has boundaries at 3 (minimum) and 10 (maximum).

KiwiSaver contribution rate — BVA test cases

  • 2-value BVA: test 2 (just below minimum — should reject), 3 (minimum — should accept), 10 (maximum — should accept), 11 (just above maximum — should reject).
  • 3-value BVA adds: 4 (just above minimum — accept) and 9 (just below maximum — accept).

The off-by-one error risk is real here: a developer coding > 3 instead of >= 3 would reject the minimum valid contribution rate, leaving employees unable to set 3%.

Try it yourself

KiwiSaver contribution rate — 2-value BVA

A KiwiSaver contribution rate field accepts whole numbers from 3 to 10 (inclusive). Using 2-value BVA, fill in all 4 boundary test values and select the expected result for each.

# Test value Expected result
1
2
3
4

Full answer — 2-value BVA for contribution rates 3–10:
#Test valueBoundary typeExpected result
12Just below lower boundaryReject
23Lower boundary (minimum)Accept
310Upper boundary (maximum)Accept
411Just above upper boundaryReject

Bonus (3-value BVA): Add 4 (just above lower boundary — Accept) and 9 (just below upper boundary — Accept).