In boundary value analysis, which values do you test for a field that accepts 1 through 60?
answer
- Faults gather where a rule flips
- Test the edge, not the middle
- One value on, one just past
- Limits come from the specification
- Empty and zero are edges too
basics
~20 sTest the edges, not the middle: 0 and 1 low, 60 and 61 high. Defects hide where a comparison flips from accept to reject, so each limit gets a value on it and one just past.
solid answer
~50 sBoundary value analysis says faults gather at the edges of an allowed range, because that is exactly where a comparison flips from accept to reject. For a field accepting 1 through 60 the two-value form gives four cases: 0 and 1 at the lower edge, 60 and 61 at the upper edge — one value sitting on each stated limit and one immediately outside it. The three-value form adds 2 and 59, the values immediately inside. The limits must be read from the specification, not from a constant found in the code, or the tests inherit whatever edge the code already believes in. A mid-range value such as 30 is still worth one case as a sanity check, but adding more of them buys almost nothing. Empty, missing and non-numeric entries are separate edges and need their own cases.
code
pseudocode · 9 linesSPEC: weekly hours accepted when 1 <= hours <= 60
two_value = [0, 1, 60, 61]
three_value = [0, 1, 2, 59, 60, 61]
expect reject(0)
expect accept(1)
expect accept(60)
expect reject(61)go deeper
Be ready to name the four values for a stated range on the spot and say which two you expect to be accepted. Interviewers use this as a quick check that you can turn a written rule into concrete cases.
Explain what each case proves — the on-limit value pins the constant, the outside value pins the direction of the comparison — and extend the idea to length, collection size and period edges rather than only numeric ranges.
Show that you also apply it to values the system computes internally, not just to form fields, and that every edge case carries a real statement of expected behaviour rather than a check that nothing blew up.
Own the tradeoff that boundary cases multiply with every limit in the rule set. Be ready to say how your teams keep the edge cases that carry consequence and stop the suite filling with edges nobody would be hurt by.
## The observation the technique rests on Boundary value analysis is built on a single empirical claim: programs go wrong at the edges of the ranges they accept, far more often than they go wrong in the middle. The reason is mechanical rather than mystical. Somewhere in the implementation a rule is expressed as a comparison, and a comparison has exactly one place where its answer changes. Everything on one side behaves identically, everything on the other side behaves identically, and the interesting event is the single step across. If the comparison uses the wrong relational operator, or the wrong constant, the mistake is visible only within one step of that edge. A value in the middle of the range cannot expose it. So the technique is a rule for spending cases where they buy something. Once you have decided that a set of values is meant to be treated the same way, you stop sampling that set randomly and start sampling it at its ends. ## Locating the boundary The boundary is a property of the specification, not of the source. For a field specified as accepting whole numbers 1 through 60, the specification names two limits, and each limit has two sides. The two-value form takes the limit itself and the nearest value outside it: 0, 1, 60, 61. The three-value form adds the nearest value inside each limit — 2 and 59 — so each boundary is probed with a below/on/above triple. A worked example makes the shape concrete. A payroll engine accepts a weekly hours entry specified as 1 through 60 hours, and rejects anything else with a validation message. The cases are: 0 hours must be rejected, 1 hour must be accepted, 60 hours must be accepted, 61 hours must be rejected. Two of those cases assert acceptance and two assert rejection, and the pair straddling each limit is what proves the limit sits where the specification put it. If the engine were written with a strict comparison at the top end, only the 60-hour case would fail; a 45-hour case would pass happily and tell you nothing. ## What each case is actually asserting The on-boundary case pins the *value* of the limit. The just-outside case pins the *direction* of the comparison. You need both, and you need a real oracle for each — a statement of what the correct behaviour is. Asserting merely that the system did not crash at 61 hours is not a boundary test; asserting that 61 hours is refused with the stated validation outcome is. ## Boundaries that are not numbers Numeric ranges are the teaching example, but most real boundaries are not numeric ranges: - **Length.** A text field specified as 3 to 12 characters has boundaries at 2, 3, 12 and 13 characters. The value of the text is irrelevant; its length is the input under test. - **Collection size.** A batch specified to accept up to 500 employee records has boundaries at an empty batch, a batch of 1, a batch of 500 and a batch of 501. Zero and one are almost always the most productive pair, because loop and aggregation code is frequently written assuming at least one element. - **Period edges.** A rule that pays a bonus for a period ending on the fifteenth has boundaries at the fourteenth, the fifteenth and the sixteenth of that period. - **Precision.** Where money or hours are recorded in fixed steps, the value just outside a limit is one step away, not one whole unit away. If hours are recorded in quarter-hour steps, the value just below 40 is 39.75. ## Why it is cheap Boundary cases are the highest-yield cases per unit of effort in most suites, because they are small, fast, deterministic and derived directly from written rules — which also makes them easy to justify to a reviewer and easy to regenerate when the rule changes. Their cost is that they multiply: every limit in every field is a candidate, and a large rule set produces more candidates than any suite can hold. ## The common ways it is done badly Three mistakes account for most of them. The first is testing only the on-boundary value and skipping the value outside, which leaves the direction of the comparison unproven. The second is reading the limit off the implementation, so the test agrees with the bug. The third is stopping at the input fields and never boundary-testing values the system computes for itself — a rounded total, an accumulated count, a derived age — where the same edges exist and nobody wrote them on a form.
- How would you apply the same technique to a field specified as 3 to 12 characters?The input under test is the length, so the cases are entries of 2, 3, 12 and 13 characters, with 4 and 11 added if you want the three-value form. The characters themselves do not matter for these cases; use the simplest content that keeps the length unambiguous. An empty entry is a separate case, because empty is usually governed by a required-field rule rather than by the length rule.
- Which boundary is most often forgotten on a collection input?The empty collection, and the collection of exactly one. Aggregation and loop code is routinely written on the assumption that something is there — a first element to compare against, a divisor that is not zero, a header row to emit. A batch of zero records and a batch of one record cost almost nothing to run and expose that assumption immediately, while a batch of five hundred usually just confirms what a batch of two already proved.
- Do you still need a mid-range case if you have covered every boundary?Usually one, as a cheap sanity check that the ordinary path works at all — a suite made only of edges can pass while the normal case is broken. But one is enough per set of values that is meant to behave identically. Adding more mid-range values is the classic way a suite grows large without getting stronger.
You do not test a fence by standing in the middle of the field. You walk right up to it, put one foot on the line, and then put one foot over.
saying these in an interview costs you the question
- Only tests the limit value, never the value just outside it
- Reads the limits out of the code instead of the specification
- Believes mid-range values are as informative as edge values
- Thinks boundaries only exist on numeric input fields
- Skips empty and zero because they look degenerate
- Asserts only that nothing crashed at the edge