Boundary Value Analysis
Bugs don't hide in the middle. They hide at the edges. Learn how to find off-by-one errors before they reach production.
1 The Hook — Why This Matters
In 2019, a Christchurch accounting firm discovered their payroll software was rejecting valid Revenue NZ numbers. The specification said Revenue NZ numbers must be between 10,000,000 and 150,000,000 inclusive. A new developer had coded if (ird > 10000000 && ird < 150000000) using strict inequalities instead of inclusive ones.
Two boundaries failed: exactly 10,000,000 and exactly 150,000,000. Both were real, valid Revenue NZ numbers held by New Zealand taxpayers. For three weeks, newly registered businesses couldn't run payroll. The developer fixed it with a single character change — but only after the firm paid emergency developer rates and issued apologies to clients.
One boundary value error cost trust and money. No amount of testing values in the middle of the range would have found it.
2 The Rule — The One-Sentence Version
Test the edges of equivalence partitions. Most bugs hide at the boundary.
Developers are human. When they write age > 18 instead of age >= 18, the defect only shows up at exactly 18. Testing 30 and 40 misses it completely. BVA is the technique that forces you to aim at the edges where these mistakes actually live.
3 The Analogy — Think Of It Like...
Testing a fence at the exact property boundary.
You can walk the entire length of a farm fence, but the only place it matters whether the post is on your side or your neighbour's is at the boundary peg. BVA doesn't test the middle of the paddock. It tests the peg, one step inside, and one step outside. That's where the disputes happen.
Senior engineer insight
Boundary value analysis clicked for me the day I watched a payroll run fail for every employee earning exactly $14,000 — the bottom of an CoverNZ levy band. The developer had written > 14000 instead of >= 14000, a single character difference that silently misfiled employer levies for 38 people. What changed how I think about BVA is this: the boundary is not just a test value — it is a contract between the spec and the code. Your job is to hold that contract to account.
The most common mistake Juniors make is testing only the valid side of a boundary and skipping the value just outside — which is exactly where the off-by-one error hides.
From the field
We were building an online KiwiSaver contribution calculator for a financial services client. The team assumed the employer contribution threshold was a simple percentage with no boundary logic — after all, KiwiSaver contribution rates are just "3%", "4%", or "10%". What they missed was the $180,000 annual income cap introduced in the 2024 Budget, above which the compulsory employer contribution calculation changes. No one had written BVA test cases for that threshold because it looked like a flat rate, not a range.
When a user entered exactly $180,000, the calculator displayed the wrong projected balance — off by nearly $2,000 over five years. We caught it in UAT because one tester happened to enter round numbers at the top of the salary range. The lesson: anywhere legislation defines a ceiling or floor, treat it as a BVA boundary, even if the underlying math looks simple on the surface.
4 Watch Me Do It — Step by Step
Here is a real NZ example using Revenue NZ number validation. Follow these steps every time you see a range in a specification.
Scenario: A tax form validates Revenue NZ numbers. The rules are: whole numbers from 10,000,000 to 150,000,000 inclusive. Anything below 10,000,000 or above 150,000,000 is rejected. Non-numeric input is rejected.
- Identify the ordered partition The valid range is 10,000,000–150,000,000 inclusive. This is an ordered numeric partition, which means BVA applies.
- Choose 2-value or 3-value BVA Use 2-value for standard regression testing (4 tests). Use 3-value for high-risk systems like tax validation, where an off-by-one error could block a legitimate taxpayer (6 tests).
-
Calculate 2-value boundary tests
For a range min to max inclusive: test min − 1, min, max, and max + 1.
- 10,000,000 − 1 = 9,999,999 (just below minimum → reject)
- 10,000,000 (minimum boundary → accept)
- 150,000,000 (maximum boundary → accept)
- 150,000,000 + 1 = 150,000,001 (just above maximum → reject)
-
Calculate 3-value additions (if needed)
Add the value just inside each boundary:
- 10,000,000 + 1 = 10,000,001 (just above minimum → accept)
- 150,000,000 − 1 = 149,999,999 (just below maximum → accept)
- Document expected results for every value Never write a boundary test without stating what should happen. Ambiguous expected results make failures impossible to judge.
- Execute and verify error messages at every boundary A boundary value that is rejected should produce a clear, helpful error message. "Invalid input" is not good enough at the edge.
| Test value | Boundary type | Expected result |
|---|---|---|
| 9,999,999 | Just below minimum | Rejected |
| 10,000,000 | Minimum boundary | Accepted |
| 150,000,000 | Maximum boundary | Accepted |
| 150,000,001 | Just above maximum | Rejected |
| Test value | Boundary type | Expected result |
|---|---|---|
| 10,000,001 | Just above minimum | Accepted |
| 149,999,999 | Just below maximum | Accepted |
> 10000000 instead of >= 10000000 would reject the minimum valid Revenue NZ number, blocking a real taxpayer. Only BVA at the boundary catches this.
Another example: A username field accepts 6–15 characters inclusive. The 2-value BVA test lengths are 5, 6, 15, and 16. Five is just below the minimum, six is the minimum boundary, fifteen is the maximum boundary, and sixteen is just above the maximum. If the developer coded > 6 instead of >= 6, only testing exactly 6 would expose the bug.
5 When to Use It / When NOT to Use It
✅ Use BVA when...
- You have ordered numeric, date, or length ranges
- The boundary logic is critical (payments, eligibility, compliance)
- The specification uses inclusive or exclusive limits
- You're testing string lengths, list sizes, or file sizes
- The system is high-risk (financial, medical, government)
❌ Don't use BVA when...
- The input is categorical and unordered (colours, country names)
- The partition has no natural ordering
- You're doing pure exploratory testing without defined ranges
- The cost of extra tests outweighs the risk (very low-impact fields)
- You haven't done EP first (BVA extends partitions; it doesn't replace them)
Before you apply BVA, ask:
- Does your input have logical partitions with defined boundaries (numeric, date, length)?
- Are the boundaries inclusive or exclusive according to the spec?
- Have you already identified partitions with equivalence partitioning?
6 Common Mistakes — Don't Do This
🚫 Testing only valid boundaries
I used to think: If the minimum and maximum boundaries work, the range is fine.
Actually: The most dangerous bugs are at 9,999,999 and 150,000,001 — the values just outside. The developer who wrote > 10000000 instead of >= 10000000 won't be caught by testing 10,000,000 alone. You must test both sides of every boundary.
🚫 Confusing inclusive with exclusive
I used to think: "Between 3 and 10" always means inclusive.
Actually: Always check the exact specification. "Between" can mean 3 < x < 10 in some systems. That changes your 2-value BVA set from {2, 3, 10, 11} to {3, 4, 9, 10}. One word in the spec changes every test case. Never assume.
🚫 Using the wrong precision
I used to think: Testing 99.9 when the boundary is $100.00 is close enough.
Actually: In New Zealand GST calculations, $0.01 rounding errors matter. If the boundary is $100.00, test exactly $99.99 and $100.00 and $100.01. "Close enough" is how $0.01 discrepancies end up in Revenue NZ filings.
When BVA fails
2-value BVA misses rounding edge cases in currency fields (e.g., $0.005 rounding to $0.00 vs. $0.01). It also misses "off-by-one" errors in inclusive/exclusive logic when the boundary value is misunderstood. Never assume the specification when inclusive vs. exclusive is ambiguous—ask the developer or product owner to clarify.
7 Now You Try — Interview Warm-Up
Question: A field accepts values from 5 to 50 inclusive. What are the 2-value BVA test cases?
Write down the four values before revealing the answer.
2-value BVA for 5–50 inclusive:
| Test value | Boundary type | Expected result |
|---|---|---|
| 4 | Just below minimum | Rejected |
| 5 | Minimum boundary | Accepted |
| 50 | Maximum boundary | Accepted |
| 51 | Just above maximum | Rejected |
Tip: If the developer coded > 5 instead of >= 5, only testing exactly 5 would catch it. And if they coded < 50 instead of <= 50, only testing exactly 50 would catch it. That's why BVA tests the boundary and its neighbours.
8 Self-Check — Can You Actually Do This?
Click each question to reveal the answer. If you got all three, you're ready to practice.
Q1. What is the difference between 2-value and 3-value BVA?
2-value BVA tests the boundary and the closest value in the adjacent partition (four values for a two-sided range). 3-value BVA adds the value just inside the boundary, giving six values total. 3-value is stronger because it catches defects like x = 10 instead of x <= 10, which 2-value can miss.
Q2. A username field accepts 6–15 characters inclusive. What are the 2-value BVA test lengths?
5, 6, 15, and 16. Five is just below the minimum, six is the minimum boundary, fifteen is the maximum boundary, and sixteen is just above the maximum. If the developer coded > 6 instead of >= 6, only testing exactly 6 would expose the bug.
Q3. Why does BVA only work on ordered partitions?
Because boundaries require a sequence. You cannot have a "value just above" a colour, a country name, or a dropdown label. BVA needs numeric, date, or length ordering so you can define what "just below" and "just above" mean.
Why teams fail here
- Testing only the "happy path" boundaries: Testers verify that the minimum and maximum valid values are accepted but never check 9,999,999 and 150,000,001 — the invalid neighbours. Off-by-one defects live outside the valid range, not inside it.
- Assuming inclusive without reading the spec: Revenue NZ income thresholds, CoverNZ levy bands, and KiwiSaver cap figures are each defined with specific inclusive/exclusive rules in legislation. Teams that assume "inclusive" without checking have repeatedly shipped calculators that misclassify people sitting exactly on the boundary.
- Skipping BVA on "simple" fields: Teams dismiss BVA for fields that look trivial — a character count, a percentage, a star rating. In practice, these low-risk-looking fields share the same
>vs>=implementation pattern and fail at boundaries just as often as financial calculations. - Using the wrong precision step: When a boundary is $100.00, testing $99.99 and $100.00 is correct — but testing $99 and $100 is not. In GST and Revenue NZ contexts, a $0.01 error at the boundary can produce a different tax liability classification. Always match the step size to the field's precision, not a convenient round number.
Key takeaway
Boundary value analysis is not about finding bugs in the middle — it is professional discipline applied to the exact line where a developer's intent and a specification's requirement must agree.
9 Interview Prep — Junior Q&A
Interviewers often ask how you approach boundaries. These are real questions you'll hear.
Q. "How is boundary value analysis different from equivalence partitioning?"
Equivalence partitioning groups inputs into categories that should behave identically. Boundary value analysis zooms in on the dividing lines between those categories, because that's where developers typically make off-by-one errors. You'd use equivalence partitioning first to identify partitions, then BVA to rigorously test the boundaries between them.
Q. "When would you use 3-value BVA instead of 2-value?"
3-value BVA is stronger when you suspect the developer might confuse operators (like < vs <=). It catches defects 2-value misses. However, 2-value is often sufficient for time-constrained testing. Choose 3-value if the boundary is critical (e.g. age verification, payment limits) or if the code is untested.
Q. "Can you apply BVA to non-numeric boundaries?"
No, BVA requires ordered partitions. It works on numbers, dates, and lengths because you can define "just above" and "just below". You cannot apply BVA to unordered data like colours, country codes, or dropdown values—equivalence partitioning alone is appropriate there.