1

I have a suite of test-classes which all implement an interface (BaseTest). This interface contains the @BeforeAll and @AfterAll lifecycle hooks, where I want these 2 hooks to execute exactly once each: once before all classes and once after all classes.

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public interface BaseTest {

    Logger logger = LoggerFactory.getLogger(BaseTest.class);

    @BeforeAll
    default void beforeAll(final TestInfo testInfo) {
        logger.info("beforeAll {}", testInfo.getTestClass());
    }

    @AfterAll
    default void afterAll(final TestInfo testInfo) {
        logger.info("afterAll {}", testInfo.getTestClass());
    }
}

Two concrete test-classes implementing this interface, for reproduction purposes:

class Test1Test implements BaseTest {
    private static final Logger logger = LoggerFactory.getLogger(Test1Test.class);

    @Test
    void testFoo1() {
        logger.info("testFoo1");
        assertTrue(true);
    }
}
class Test2Test implements BaseTest {
    private static final Logger logger = LoggerFactory.getLogger(Test2Test.class);

    @Test
    void testFoo2() {
        logger.info("testFoo2");
        assertTrue(true);
    }
}

When running these 2 tests I get the following output:

beforeAll Optional[class Test1Test]
testFoo1
afterAll Optional[class Test1Test]
beforeAll Optional[class Test2Test]
testFoo2
afterAll Optional[class Test2Test]

Versions: Using JUnit 5.9.2 and Maven Surefire plugin 3.0.0-M8.

This is not what I expect, and this is not what the documentation specifies, since I put the lifecycle hooks in the base interface shared by both test-classes. Note that I get the same behavior with an (abstract) base class instead of the interface.

Question Do I misunderstand the lifecycle possibilities, or is there something else I am forgetting?

Bossk
  • 707
  • 8
  • 24
  • 2
    Your expectations are wrong. `@BeforeAll` runs for each class before all the methods the same for `@AfterAll`. If you want those to run only ones I believe you would need to create an `@Suite` annotated class which runs the classes and put the annotations on that (but as you are using subclasses you probably need sometihgn from those methods in your test). – M. Deinum Jan 31 '23 at 07:39
  • 1
    Have a look at the following answer to a slightly different question: https://stackoverflow.com/questions/75290490/junit5-before-and-after-suite-method-invocation/75294430#75294430 – johanneslink Jan 31 '23 at 11:15
  • @M.Deinum `@Suite` classes cannot be annotated with Jupiter annotations. – johanneslink Jan 31 '23 at 11:16

0 Answers0