Part 3: Testing with Faktor-IPS

A JUnit-Adapter for Faktor-IPS Test Cases

The Faktor-IPS Runtime includes an adapter to convert Faktor-IPS test cases into JUnit test cases or test suites. This way, Faktor-IPS test cases can also be executed with Gradle or Maven, because these tools provide a suitable JUnit integration. At the same time, this enables effortless automatic execution of Faktor-IPS test cases within a continuous integration environment.

We can use the following code to create an adapter that converts our Faktor-IPS test cases into a JUnit 3/JUnit 4 test suite:

import org.faktorips.runtime.ClassloaderRuntimeRepository;
import org.faktorips.runtime.IRuntimeRepository;
import org.faktorips.runtime.test.IpsTestSuiteJUnitAdapter;

import junit.framework.Test;

public class HomeContentsJUnit3Test extends IpsTestSuiteJUnitAdapter {

    public static Test suite() {
        IRuntimeRepository repositoryHomeContents = ClassloaderRuntimeRepository.create(
                "org/faktorips/tutorial/productdata/internal/faktorips-repository-toc.xml");

        return createJUnitTest(repositoryHomeContents.getIpsTest(""));
    }
}

With the following code we create an adapter, that converts our Faktor-IPS test cases into JUnit 5 Dynamic Tests:

import org.faktorips.runtime.ClassloaderRuntimeRepository;
import org.faktorips.runtime.IRuntimeRepository;
import org.faktorips.runtime.test.IpsTestSuiteJUnit5Adapter;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

public class HomeContentsJUnit5Test extends IpsTestSuiteJUnit5Adapter {

    @TestFactory
    public Stream<DynamicTest> getTests() {
        IRuntimeRepository repositoryHomeContents = ClassloaderRuntimeRepository.create(
                "org/faktorips/tutorial/productdata/internal/faktorips-repository-toc.xml");

        return createTests(repositoryHomeContents.getIpsTest(""));
    }
}

We create a RuntimeRepository populated with the product data and call the getIpsTest("") method to provide us a test suite with all the test cases stored in the repository. For JUnit 3/JUnit 4 the createJUnitTest(…​) method of class IpsTestSuiteJUnitAdapter takes the test suite and makes it a JUnit test suite. For JUnit 5 the method createTest(…​) of class IpsTestSuiteJUnit5Adapter returns a Stream of DynamicTests. If we execute the test class with the respective JUnit-Testrunner, we can see how our Faktor-IPS test cases are executed and interpreted by JUnit.

junit test
Figure 1. Running a test adapter in the JUnit GUI

Configuration of the Maven Surefire Plugin for JUnit 5 tests

In the test reports of the Maven Surefire Plugin, the dynamic tests generated from the IPS test cases are not listed with their display names (the IPS test case names) but with the name of the method that is annotated with @TestFactory. For example, the code sample above would generate a test report listing three tests named "getTests". That makes it impossible to find out from the test report which IPS test cases have failed.

This problem can be solved by configuring the plugin in the pom.xml as follows. The correct display names of the dynamic tests will then be used in the test reports.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M6</version>
    <configuration>
        <statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
            <usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
        </statelessTestsetReporter>
        <argLine>-Dfile.encoding="UTF-8"</argLine>
    </configuration>
</plugin>