Getting started with JUnit 5 TestSuite

JUnit 5 provides powerful features for organizing and running tests efficiently. Test Suites, a collection of tests bundled together, allow you to execute multiple test classes or methods in one go. In this article we will show a step-by-step guide to create a JUnit 5 TestSyite with some practical examples.

How to declare a JUnit 5 Test Suite

Firstly, if you are new to JUnit, we recommend checking this article: JUnit 5 : Step-by-step Tutorial

A JUnit 5 TestSuite enables to run multiple tests together. To aggregate multiple Tests in a TestSuite you can use the following annotations:

  • @SelectPackages – specifies the names of packages for the test suite
  • @SelectClasses – specifies the classes for the test suite. They can be located in different packages.

Here is an example TestSuite which uses both annotation to select two Test Classes and a package:

import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.runner.RunWith;


@RunWith(JUnitPlatform.class)
@SelectClasses( { Math1Test.class, Math2Test.class } )
@SelectPackages("com.example.project")
public class TestSuiteDemo {
}

Coding the Test Classes

Next, let’s code the two Java Classes Math1Test and Math2Test which are part of our Test Suite. Let’s begin with Math1Test:

package com.example.project;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class Math1Test {

    @Test
    public void testAddition() {
        int result = Calculator.add(3, 7);
        Assertions.assertEquals(10, result, "3 + 7 should equal 10");
    }

    @Test
    public void testSubtraction() {
        int result = Calculator.subtract(10, 4);
        Assertions.assertEquals(6, result, "10 - 4 should equal 6");
    }
}

Then, here is Math2Test Class:

package com.example.project;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class Math2Test {

    @Test
    public void testMultiplication() {
        int result = Calculator.multiply(5, 6);
        Assertions.assertEquals(30, result, "5 * 6 should equal 30");
    }

    @Test
    public void testDivision() {
        double result = Calculator.divide(20, 5);
        Assertions.assertEquals(4.0, result, "20 / 5 should equal 4.0");
    }
}

As you can see, both Test Classes are Testing the Calculator Class which contains all the four basic arithmetic operations:

package com.example.project;
 

public class Calculator {

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

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

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

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

Building the Test Suite:

In order to build the project, make sure you include the JUnit 5 BOM File and, besides the Engine and the API, include also the PlatFormRunner which is essential for the JUnit TestSuite:

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.junit</groupId>
			<artifactId>junit-bom</artifactId>
			<version>5.10.1</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
<dependencies>
	<dependency>
		<groupId>org.junit.platform</groupId>
		<artifactId>junit-platform-runner</artifactId>
	</dependency>
	<dependency>
		<groupId>org.junit.jupiter</groupId>
		<artifactId>junit-jupiter-engine</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.junit.jupiter</groupId>
		<artifactId>junit-jupiter-api</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

Here is the Project View of our TestSuite:

JUnit 5 Test Suite Example tutorial

Running the TestSuite

Switch to the Test perspective of your IDE and execute the TestSuiteDemo Class:

JUnit 5 TestSuite step-by-step guide

As you can see, the execution of the TestSuiteDemo Class triggered the execution of both Math1Test and Math2Test.

Creating Dynamic Tests with the @TestFactory Annotation

JUnit 5 dynamic tests allow you to declare and execute test cases generated at runtime. Unlike static tests, which define a fixed number of test cases at compile time, dynamic tests enable dynamically defining test cases at runtime.

Dynamic tests can be generated by a method annotated with @TestFactory:

import org.junit.jupiter.api.*;
import org.junit.platform.suite.api.*;

public class DynamicTestSuite {

    @TestFactory
    public TestSuite dynamicTestSuite() {
        return TestSuite.create("Dynamic Test Suite")
                .includePackages("com.example.project")
                .selectClass(MathTest.class)
                .selectClass(MathTest2.class)
                .build();
    }
}

Conclusion:

JUnit 5 Test Suites provide a flexible and powerful way to organize and execute tests in your Java projects. Leveraging advanced features such as conditional execution, test ordering, tags, and parameterized tests enhances the efficiency and readability of test suites.

Source code: https://github.com/fmarchioni/mastertheboss/tree/master/test/junit5-testsuite