There are situations where, when one test in a class fails, the remaining tests in the class don’t need to be executed because their results offer little additional insight.
In those situations, disabling the remaining tests can be preferable in order to avoid larger build logs and/or reduce the test suite’s overall run time.
By applying @DisableIfTestFails to the test class, all tests after the first failed one are disabled.
@DisableIfTestFails
When applied to a type, @DisableIfTestFails will disable all tests that are launched after the first failing test in that class:
@DisableIfTestFails
// this annotation ensures that tests are run in the order of
// the numbers passed to the `@Order` annotation below
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class Tests {
@Test
@Order(1)
void test1() {
}
@Test
@Order(2)
void test2() {
fail("fails");
}
@Test
@Order(3)
void test3() {
}
}
In this example, test1 will pass and test2 will fail with or without the extension but due to @DisableIfTestFails, test3 will be disabled (instead of being executed).
The extension ignores aborted tests (e.g. due to failed assumptions) and won’t disable tests because of that. By default, it will disable remaining tests on any exception, including failed assertions - both of that can be configured.
Not disabling on failed assertions
By default, @DisableIfTestFails will disable remaining tests on failed assertions.
If instead, failed assertions are acceptable and only other test failures should lead to disabling, set onAssertion = false:
@DisableIfTestFails(onAssertion = false)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ThreeTestsWithSecondFailingWithUnconfiguredAssertionTestCase {
@Test
@Order(1)
void test1() {
}
@Test
@Order(2)
void test2() {
// fails test with assertion
assertThat(false).isTrue();
}
@Test
@Order(3)
void test3() {
}
}
The test test2 fails because of an assertion but due to onAssertion = false, test3 isn’t disabled and will execute.
Disabling on specific exceptions
By default, @DisableIfTestFails will disable remaining tests on any exception.
If instead, only specific exceptions should lead to disabling, define them with with:
@DisableIfTestFails(with = IOException.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ThreeTestsWithSecondThrowingConfiguredExceptionTestCase {
@Test
@Order(1)
void test1() {
}
@Test
@Order(2)
void test2() throws InterruptedException {
throw new InterruptedException();
}
@Test
@Order(3)
void test3() throws IOException {
throw new IOException();
}
@Test
@Order(4)
void test4() {
}
}
The test test2 fails, but because the with attribute doesn’t include its exception’s type InterruptedException, tests will continue to be executed.
Then test3 fails with the configured exception and so test4 is disabled.
Inheritance
The annotation can be applied to classes and interfaces that have further implementations, which means any specific test class might inherit/implement from multiple types that have @DisableIfTestFails annotations.
In that case, the extension disables the maximum number of tests:
-
the exception types given to
withare merged, i.e. tests are disabled if a test fails with any of the configured exceptions -
onAssertionis or’ed, i.e. only if all are configured to keep executing on a failed assertion, will that happen
But if a test fails in a specific class, only other tests in the same class will be disabled. That means if…
-
a test class
SpecificTestsimplements interfaceTestsand -
Testsis annotated with@DisableIfTestFailsand -
a test in
SpecificTestsfails-
then, only remaining tests in
SpecificTestsare disabled and other implementations ofTestsremain unaffected, i.e. their tests are not disabled.
-
Thread-Safety
This extension is safe to use during parallel test execution, but no guarantee can be given how soon after a failed test other tests will be disabled, i.e. how soon other threads observe that "their" tests are supposed to be disabled.