Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java parameterized tests: boundary cases without arithmetic overflow

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A parameterized test applies one stated behavior to several input cases while keeping each failing case identifiable in the runner.

Download Java source kit

Java 21+. These tests require JUnit Jupiter 5.11.0; the downloadable Maven project declares it.

Choose boundaries that distinguish implementations

The packing function returns the number of vehicles needed for a non-negative parcel count and a positive capacity. The common expression (parcels + capacity - 1) / capacity can overflow before division. Division plus a remainder check keeps the valid maximum-int input representable.

The valid table includes zero, an exact multiple, one over capacity and Integer.MAX_VALUE. The invalid table verifies negative parcel count and non-positive capacity. Adding many repeated ordinary cases would not distinguish the overflowing formula from this implementation.

This sample uses JUnit Jupiter 5.11.0 in the downloadable Maven project. The annotation API requires the matching test dependencies and runner; copying the Java file alone into a plain javac invocation does not make it executable.

Working program

Java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.*;
public class PackingBoundaryTest {
    static int vehicles(int parcels,int capacity){
        if(parcels<0||capacity<=0)throw new IllegalArgumentException("Invalid packing inputs");
        return parcels/capacity+(parcels%capacity==0?0:1);
    }
    @ParameterizedTest
    @CsvSource({"0,4,0","1,4,1","8,4,2","9,4,3","2147483647,2,1073741824"})
    void validInputs(int parcels,int capacity,int expected){assertEquals(expected,vehicles(parcels,capacity));}
    @ParameterizedTest
    @CsvSource({"-1,4","1,0","1,-4"})
    void rejectsInvalidInputs(int parcels,int capacity){assertThrows(IllegalArgumentException.class,()->vehicles(parcels,capacity));}
}

Runner contract

Output
The JUnit runner evaluates five valid cases and three rejected-input cases.

Costs and boundaries

Each calculation is O(1) work and storage. The test table verifies specified boundaries rather than performance. JUnit assertions execute without the JVM -ea flag. A parameterized runner reports individual invocations so the maximum-int failure can be identified directly.

Common Mistakes

  • The addition-based ceiling formula can overflow.
  • A Java annotation alone does not install a test runner.
  • Do not replace rejection checks with a print-only catch block.

Read next

Test runner setup, Arithmetic representation.

java
parameterized-tests
Storage details