Software QA / Basic: reasoning and test design / Lesson 4
Equivalence partitions and boundary values
Choose a small, defensible set of inputs from a large domain. Work through enrollment ages, quantities, and string lengths while keeping assumptions and expected rejections explicit.
On this page
Lesson goals
- Partition a domain using expected behavior.
- Select values on and around boundaries.
- Recognize limits of partition assumptions.
Group values by behavior
Suppose a workshop accepts whole-number ages from 16 through 65 inclusive. Begin with three ordered partitions: below 16, 16–65, and above 65. Add separate type partitions for missing values, decimals, and nonnumeric strings if the interface can receive them. Equivalence means a reasoned expectation that values in one group receive the same relevant treatment. It is a model, not an established fact about the implementation. A representative value reduces the sample while boundary checks challenge common mistakes at transitions between groups.
Worked case: age eligibility
A central value such as 35 samples the valid partition, but it will not distinguish “greater than 16” from “at least 16.” Choose 15, 16, 17 and 64, 65, 66 to inspect the boundary and immediate neighbors. State the precision: these neighbors are meaningful because the accepted domain is whole years. The expected rejection includes no enrollment record, not merely a red field. Check an invalid type separately so a parsing failure is not confused with a valid numeric value outside the allowed range.
Input | Expected
15 | reject; no enrollment
16, 17, 64, 65 | accept if other conditions hold
66 | reject; no enrollment
"sixteen" | type validation error
Other conditions are held valid, isolating the age rule. The string case probes a different partition.
Define the unit being bounded
For a display name limited to 40 characters, clarify whether “character” means bytes, Unicode code points, or user-perceived grapheme clusters. An Arabic name with combining marks can expose disagreement between client and server counters. Test the agreed unit with lengths 39, 40, and 41, plus empty and whitespace-only values according to the requirement. Do not assume that a database column length is the product’s user-facing rule. Normalize only when specified, since silently trimming or rewriting input can change names or identifiers that users intend to preserve.
Worked case: quantities and invalid combinations
A resource checkout accepts integer quantities from 1 to 10 and has five items in stock. There are two different boundaries: permitted request quantity and available stock. For quantity 6, the format/range rule succeeds but the stock rule rejects. Use stock 10 when isolating the maximum quantity, and use quantity 5 and 6 when isolating stock. Combining every invalid input at once can hide missing validators: a rejection caused by stock says nothing about whether a negative quantity would also be rejected.
Stock | Quantity | Expected reason
10 | 10 | accept maximum
10 | 11 | quantity exceeds permitted maximum
5 | 5 | accept available stock
5 | 6 | insufficient stock
Expected reasons distinguish which rule the test investigates, instead of accepting any error.
Challenge the model with evidence
Partition coverage reports whether each modeled group was sampled. It does not imply every member behaves identically. Parsing limits, overflow, localization, or special values may split a partition you initially considered uniform. Add examples when a defect reveals such a split and explain why the model changed. For continuous measurements, pick neighbors using the supported precision rather than an imaginary universal epsilon. Save the chosen values and oracle rationale so another tester can reproduce the design and judge whether the sampled domain still reflects the current rules.
Common errors and fixes
Testing only the middle of the valid range
- Why it happens
- The sample avoids comparison boundaries.
- How to fix it
- Add each boundary and supported neighboring values.
- Prevent it next time
- Write partitions before choosing examples.
Calling every rejection a pass
- Why it happens
- An unrelated validator masks the rule under test.
- How to fix it
- Hold other inputs valid and assert the intended error and side effects.
- Prevent it next time
- Record expected rejection reasons.
Assuming character limits equal byte limits
- Why it happens
- Encoding and product language are conflated.
- How to fix it
- Agree the counting unit and test multilingual examples.
- Prevent it next time
- Review text rules across interface, API, and storage.
Check your understanding
1. An integer percentage must be between 0 and 100 inclusive. Give boundary cases.
Show worked solution
Use -1, 0, 1, 99, 100, and 101. Expect rejection for -1 and 101 and acceptance for the others with valid surrounding data. Add missing, decimal, and nonnumeric values as distinct type partitions if the interface accepts those representations.
2. A cart rejects quantity 11 when stock is 3. Does that prove the maximum-10 rule?
Show worked solution
No. Stock validation could be the only cause. Set stock to at least 11 in an isolated fixture, then compare quantity 10 with 11. Assert the maximum-quantity error for 11 and no inventory change; separately test the stock boundary.
Key takeaways
- Partition by expected treatment, then challenge transitions.
- A rejected input is informative only when its oracle identifies the relevant rule.