Loading published curriculum…

18 · Testing the complete backend / LESSON 88 OF 102

JUnit lifecycle and parameterized tests

A test should expose a specific defect through a precise observable assertion.

Before this lesson: Version the database schema

Understand the topic

Arrange the inputs, invoke behavior, and assert the contract. Keep tests independent of execution order and wall-clock time. @BeforeEach sets up per-test state; shared mutable fixtures can make one test accidentally prepare another.

Parameterized tests run the same contract over a small meaningful input matrix. Include normal values, boundaries, and invalid inputs. A high coverage percentage does not prove assertions would catch a defect; introduce a deliberate bug locally to check test sensitivity.

EXAMPLE · JAVA

PagePolicyTest.java

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
class PagePolicyTest {
 @ParameterizedTest @ValueSource(ints = {1, 20, 100})
 void acceptsBoundedSizes(int size) {
  assertEquals(size, PagePolicy.checkedSize(size));
 }
 @ParameterizedTest @ValueSource(ints = {-1, 0, 101})
 void rejectsInvalidSizes(int size) {
  assertThrows(IllegalArgumentException.class, () -> PagePolicy.checkedSize(size));
 }
}

What to expect

Place beside the PagePolicy class from the pagination lesson with the Boot test dependencies. Six cases verify both acceptance and rejection boundaries.

YOUR TURN

Put it into practice

  1. 01Build a parameterized matrix for title validation.
  2. 02Introduce an off-by-one defect in maximum length and confirm a case fails.
  3. 03Verify: Tests run independently and fail for a known incorrect implementation.

Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.

UNDER THE HOOD

Build the mental model

A test should expose a specific defect through a precise observable assertion.

  1. 01Arrange the inputs, invoke behavior, and assert the contract. Keep tests independent of execution order and wall-clock time. @BeforeEach sets up per-test state; shared mutable fixtures can make one test accidentally prepare another.
  2. 02Parameterized tests run the same contract over a small meaningful input matrix. Include normal values, boundaries, and invalid inputs. A high coverage percentage does not prove assertions would catch a defect; introduce a deliberate bug locally to check test sensitivity.
  3. 03Trace the example: Place beside the PagePolicy class from the pagination lesson with the Boot test dependencies. Six cases verify both acceptance and rejection boundaries.

A mistake worth avoiding

Tests pass individually but fail when run together.

DEBUGGING ROOM

Something broke. Where do you look?

Tests pass individually but fail when run together.

Before revealing the diagnosis, write down your first investigation step.

CHECK YOUR UNDERSTANDING

Does line coverage alone prove a test would detect incorrect results?

Choose one answer

BUILD IT YOURSELF

Build a parameterized matrix for title validation.

  1. 1.Build a parameterized matrix for title validation.
  2. 2.Introduce an off-by-one defect in maximum length and confirm a case fails.
  3. 3.Reproduce this failure, then repair it: Tests pass individually but fail when run together.

Acceptance checklist

Lab completion is your self-report. Knowledge checks do not certify project quality.

RETRIEVE IT FROM MEMORY

Does line coverage alone prove a test would detect incorrect results?

Revisit this lesson in three days after a successful check or lab.

Ready for the next step?

Tests run independently and fail for a known incorrect implementation.

Reading is separate from passing a knowledge check or completing a lab.

Go deeper · official references