← Articles

Boundary tests in Java: why a passing test is not enough

A small function, two cases and a bug that a green test can miss.

Underlined terms have explanations. Copy the code and run it locally.

Contents and terms

Terms at hand

Select a term to see its definition.

Full glossary →

A green test can miss the bug

An event has ten seats, three already reserved. Seven remain. A test using only this input misses an implementation that incorrectly returns at least one seat even when the event is full.

Predict before running

Save this complete example as Seats.java. With 25, run java Seats.java. It needs no framework, or dependencies.

java
public class Seats {
    static int available(int capacity, int reserved) {
        if (capacity < 0 || reserved < 0 || reserved > capacity) {
            throw new IllegalArgumentException("Invalid counts");
        }
        return capacity - reserved;
    }
    static void equal(int expected, int actual) {
        if (expected != actual) throw new AssertionError(expected + " != " + actual);
    }
    public static void main(String[] args) {
        equal(7, available(10, 3));
        equal(0, available(3, 3));
        System.out.println("PASS: ordinary and full-capacity cases");
    }
}

The output is PASS: ordinary and full-capacity cases. Parameters are the 's inputs; return passes back the calculated value. equal throws an error when the actual result differs from the expectation. No -ea flag is required: this example throws explicitly instead of using 's assert keyword.

Make the test detect a mistake

Replace the return expression with Math.max(1, capacity - reserved). The ten-seat example still returns seven. The full-capacity case now throws an AssertionError: it expected zero and received one. subtraction.

A test is useful when it distinguishes the rule from a plausible mistake. Its value is not the number of green lines.

Your attempt

Before running, predict available(0, 0) and add its expectation. Then try available(3, 4) separately: must reject it. Returning zero would conceal invalid input.

Tomorrow, write the same rule for unread book pages without looking here. Which input distinguishes “nothing remains” from “the input is invalid”?

What this does not prove

Counting seats does not reserve one. Two clients may read the same count. The later database write needs its own and conflict protection. Start with the function; learn that boundary next.

Sources

CHECK YOUR INTUITION

Which case distinguishes subtraction from a minimum of one seat?

NOW WRITE YOUR OWN CODE

Put your understanding into practice.

Open the Java pilot: your own file, a test and an available-seats task.

Open the learning material →