On Thu, 19 Feb 2026 08:33:10 GMT, Volkan Yazici <[email protected]> wrote:

>> When using 
>> [TestInstance.Lifecycle.PER_CLASS](https://docs.junit.org/5.0.0/api/org/junit/jupiter/api/TestInstance.html)
>>  then a single instance of the class will be used to invoke all test 
>> methods. It makes it possible to use `@BeforeAll` `@AfterAll` to setup and 
>> teardown objects/variables that all tests methods depend on. Typically in 
>> the `HttpClient` tests we use that to start, and then stop, the `HttpServer` 
>> instances that all test methods will interact with. AFAIU that was the 
>> default with TestNG - but the JUnit default is to create one instance of the 
>> test class for each test method invocation. Using 
>> `TestInstance.Lifecycle.PER_CLASS` makes it easier to migrate from TestNG to 
>> JUnit.
>
>> When using 
>> [TestInstance.Lifecycle.PER_CLASS](https://docs.junit.org/5.0.0/api/org/junit/jupiter/api/TestInstance.html)
>>  then a single instance of the class will be used to invoke all test 
>> methods. It makes it possible to use `@BeforeAll` `@AfterAll` to setup and 
>> teardown objects/variables that all tests methods depend on.
> 
> @dfuch, AFAICT, as long as your shared state is in `static` variables, 
> `@BeforeAll`/`@AfterAll` will be executed _once_ even if test methods use 
> different instances. Consider the following example:
> 
>     /* @test
>      * @run junit ${test.main.class} */
>     
>     import org.junit.jupiter.api.BeforeAll;
>     import org.junit.jupiter.api.Test;
>     
>     class FooTest {
>         private static int X;
>         @BeforeAll static void beforeAll() { System.err.println("beforeAll"); 
> X = 1; }
>         FooTest() { System.err.println("ctor"); }
>         @Test void test1() { System.err.println("test1's X:" + X); }
>         @Test void test2() { System.err.println("test2's X:" + X); }
>     }
> 
> `make run-test TEST=/path/to/FooTest.java` will produce the following JTReg 
> output:
> 
>     beforeAll
>     ctor
>     [09:24:27.225] STARTED    FooTest::test1 'test1()'
>     test1's X:1
>     [09:24:27.233] SUCCESSFUL FooTest::test1 'test1()' [8ms]
>     ctor
>     [09:24:27.234] STARTED    FooTest::test2 'test2()'
>     test2's X:1
>     [09:24:27.235] SUCCESSFUL FooTest::test2 'test2()' [0ms]
> 
> Above test output indicates that
> 
> 1. `beforeAll()` is executed once
> 2. Both `test1` and `test2` observe the same `X`
> 
> In conclusion, I think we can do without any `@TestInstance`. If you think 
> otherwise, would you mind helping me to understand, please?

As it happens most of the tests I converted have shared instance variables that 
are set up and teared down by non-static methods annotated with `@BeforeAll` 
and `@AfterAll`. And `LifeCycle.PER_CLASS` helps preserving the previous 
(testNG) behavior. I don't see a need to change that - or to remove that 
annotation.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/29786#discussion_r2826513725

Reply via email to