JUnit Dynamic Tests

Introduction

In this chapter, we will explore JUnit dynamic tests. Dynamic tests allow you to create and execute tests programmatically at runtime. This is useful when the number of tests or their inputs are not known until execution time, providing flexibility and power in your testing strategy.

What are Dynamic Tests?

Dynamic tests in JUnit are tests that are generated at runtime using the DynamicTest class. Unlike static tests, which are defined at compile-time, dynamic tests allow you to create tests programmatically. This is particularly useful for scenarios where the test cases need to be generated based on external data or runtime conditions.

Dynamic tests are created using the DynamicTest class and the dynamicTest factory methods provided by JUnit. These tests can be grouped and returned as a collection of DynamicNode instances from a factory method annotated with @TestFactory.

Example: Creating Dynamic Tests

Let’s create an example to demonstrate how to use dynamic tests in JUnit.

Step 1: Create a Class Under Test

Calculator Class

The Calculator class will have basic arithmetic operations.

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }

    public int divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Division by zero");
        }
        return a / b;
    }
}

Step 2: Create a Test Class with Dynamic Tests

CalculatorTest

The CalculatorTest class will contain dynamic tests for the Calculator class.

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.function.Executable;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

public class CalculatorTest {

    private final Calculator calculator = new Calculator();

    @TestFactory
    Collection<DynamicTest> dynamicTestsForAddition() {
        return Arrays.asList(
            dynamicTest("1 + 1 = 2", () -> assertEquals(2, calculator.add(1, 1))),
            dynamicTest("2 + 3 = 5", () -> assertEquals(5, calculator.add(2, 3))),
            dynamicTest("3 + 5 = 8", () -> assertEquals(8, calculator.add(3, 5)))
        );
    }

    @TestFactory
    Stream<DynamicTest> dynamicTestsForSubtraction() {
        return Stream.of(
            new TestCase(5, 3, 2),
            new TestCase(10, 5, 5),
            new TestCase(3, 2, 1)
        ).map(testCase -> dynamicTest(
            testCase.inputA + " - " + testCase.inputB + " = " + testCase.expected,
            () -> assertEquals(testCase.expected, calculator.subtract(testCase.inputA, testCase.inputB))
        ));
    }

    static class TestCase {
        final int inputA;
        final int inputB;
        final int expected;

        TestCase(int inputA, int inputB, int expected) {
            this.inputA = inputA;
            this.inputB = inputB;
            this.expected = expected;
        }
    }
}

Important Points

  • @TestFactory: Use this annotation to mark a method as a factory for dynamic tests. The method must return a Stream, Collection, Iterable, or array of DynamicNode instances.
  • DynamicTest: Use the DynamicTest.dynamicTest factory method to create dynamic tests. Each dynamic test requires a display name and an Executable (typically a lambda) containing the test logic.

Running the Dynamic Tests

To run the dynamic tests, simply run the CalculatorTest class as a JUnit test. This will execute all dynamic test methods, generating and running tests at runtime.

Using IntelliJ IDEA

  1. Run Tests: Click the green run icon next to the CalculatorTest class and select Run.
  2. View Results: The results will be displayed in the Run window, showing the dynamically generated tests.

JUnit Dynamic Tests

Using VS Code

  1. Run Tests: Open the CalculatorTest file and click the Run icon above the class declaration.
  2. View Results: The results will be displayed in the Test Explorer, showing the dynamically generated tests.

Using Eclipse

  1. Run Tests: Right-click on the CalculatorTest file and select Run As > JUnit Test.
  2. View Results: The results will be displayed in the JUnit view, showing the dynamically generated tests.

Conclusion

JUnit dynamic tests provide a flexible way to generate and run tests programmatically at runtime. By using the @TestFactory annotation and the DynamicTest class, you can create dynamic tests based on runtime conditions or external data, avoiding the need for duplicative test methods. This approach helps in creating more maintainable and adaptable test suites for complex testing scenarios.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top