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.