Apache Maven

Recording test failures under Apache Maven *

See Recording test failures for an overview of LR4J test integration.

The following instructions apply to Apache Maven used with the Surefire or Failsafe plugins.

1. Maven: record all tests and generate one recording file per failing test class

This is the least intrusive method of integration since it doesn’t require build changes. Add the following rule to each of your test classes:

@Rule
public final TestRule watchman =
    new TestWatcher() {
        protected void failed(Throwable thr, Description description) {
            // Tell LiveRecorder to name the recording file after this
            // failing method & class
            System.setProperty("io.undo.output", description.toString());
            // Tell LiveRecorder that the test failed
            System.setProperty("io.undo.failed", "true");
        }
    };

Add the following to the configuration section in the maven-surefire-plugin and/or maven-failsafe-plugin sections of your pom.xml file:

<configuration>
    ...
    <!-- Add LiveRecorder agent to Java command-line -->
    <argLine>-XX:-Inline -XX:TieredStopAtLevel=1 -XX:UseAVX=2 -agentpath:/path/to/lr4j-record-1.0.so=save_on=failure</argLine>
    <!-- Stop at first failure -->
    <skipAfterFailureCount>1</skipAfterFailureCount>
    ...
</configuration>

And ensure that the maven-surefire-plugin and/or maven-failsafe-plugin sections of your pom.xml file do not include a <parallel> attribute.

This configuration causes the test run to stop at the first method in a class that fails so that each recording file contains exactly one test failure, and that failure is located at the end of the recording (though the recording file may contain some earlier test successes too). You can omit the <skipAfterFailureCount> attribute, in which case the recording may contain multiple test successes and failures and will be named after the last failing method.

2. Maven: record all tests and generate one recording file per failing test method

Add the following rule to each of your test classes:

@Rule
public final TestRule wrapper =
        new TestRule() {
            @Override
            public Statement apply(final Statement base, final Description description) {
                return new Statement() {
                    @Override
                    public void evaluate() throws Throwable {
                        UndoLR.setEventLogSize(1000 * 1000 * 1000);
                        UndoLR.start();
                        try {
                            base.evaluate();
                        } catch (Throwable e) {
                            UndoLR.save(description + ".undo");
                        } finally {
                            UndoLR.stop();
                        }
                    }
                };
            }
        };

Add the LiveRecorder API to your local repository:

$ mvn install:install-file \
-Dfile=/path/to/lr4j/lr4j_api-1.1.jar \
-DgroupId=io.undo.jdwp \
-DartifactId=lr4j_api \
-Dversion=1.1 \
-Dpackaging=jar

Include the LiveRecorder API as a build and runtime dependency in your pom.xml file:

<dependency>
    <groupId>io.undo.jdwp</groupId>
    <artifactId>lr4j_api</artifactId>
    <version>1.1</version>
</dependency>

Add the following to the configuration section in the maven-surefire-plugin and/or maven-failsafe-plugin sections:

<configuration>
    ...
    <!-- Add LiveRecorder agent to Java command-line -->
    <argLine>-XX:-Inline -XX:TieredStopAtLevel=1 -XX:UseAVX=2 -agentpath:/path/to/lr4j-record-1.0.so</argLine>
    ...
</configuration>

And ensure that the maven-surefire-plugin and/or maven-failsafe-plugin sections of your pom.xml file do not include a <parallel> attribute.

This configuration causes each test to be recorded but the recording will only be saved on failure. Note that you must not use <parallel>methods</parallel> - that records tests in parallel threads and only one pairing of UndoLR.start/UndoLR.stop should be active at any one time in the process.

3. Maven: run all tests, and re-run failing test methods under recording

The following instructions are for JUnit 4. For JUnit 5 see the rerunner-jupiter extension.

Add the following rule to each of your test classes:

static Set<String> hadFailure = new HashSet<String>();

@Rule
public final TestRule wrapper =
        new TestRule() {
            @Override
            public Statement apply(final Statement base, final Description description) {
                return new Statement() {
                    @Override
                    public void evaluate() throws Throwable {
                        if (hadFailure.contains(description.toString())) {
                            UndoLR.setEventLogSize(1000 * 1000 * 1000);
                            UndoLR.start();
                            try {
                                base.evaluate();
                            } catch (Throwable e) {
                                UndoLR.save(description + ".undo");
                                throw e;
                            } finally {
                                UndoLR.stop();
                            }
                        } else {
                            try {
                                base.evaluate();
                            } catch (Throwable e) {
                                hadFailure.add(description.toString()); // record next time
                                throw e;
                            }
                        }
                    }
                };
            }
        };

Add the LiveRecorder API to your local repository:

$ mvn install:install-file \
-Dfile=/path/to/lr4j/lr4j_api-1.1.jar \
-DgroupId=io.undo.jdwp \
-DartifactId=lr4j_api \
-Dversion=1.1 \
-Dpackaging=jar

Include the LiveRecorder API as a build and runtime dependency in your pom.xml file:

<dependency>
    <groupId>io.undo.jdwp</groupId>
    <artifactId>lr4j_api</artifactId>
    <version>1.1</version>
</dependency>

Add the following to the configuration section in the maven-surefire-plugin and/or maven-failsafe-plugin sections:

<configuration>
    ...
    <!-- Add LiveRecorder agent to Java command-line -->
    <argLine>-XX:-Inline -XX:TieredStopAtLevel=1 -XX:UseAVX=2 -agentpath:/path/to/lr4j-record-1.0.so</argLine>
    <!-- Re-run failing tests -->
    <rerunFailingTestsCount>1</rerunFailingTestsCount>
    <!-- Ensure that failing test is executed in the same JVM instance -->
    <forkCount>1</forkCount>
    <reuseForks>true</reuseForks>
    ...
</configuration>

And ensure that the maven-surefire-plugin and/or maven-failsafe-plugin sections of your pom.xml file do not include a <parallel> attribute.

*

Apache Maven and the Apache Ant project logo are trademarks of the Apache Software Foundation in the United States and/or other countries. No endorsement by The Apache Software Foundation is implied by the use of these marks.