What use is @TestInstance annotation in JUnit 5?

I think the docs provide a useful summary:

If you would prefer that JUnit Jupiter execute all test methods on the same test instance, simply annotate your test class with @TestInstance(Lifecycle.PER_CLASS). When using this mode, a new test instance will be created once per test class. Thus, if your test methods rely on state stored in instance variables, you may need to reset that state in @BeforeEach or @AfterEach methods.

The "per-class" mode has some additional benefits over the default "per-method" mode. Specifically, with the "per-class" mode it becomes possible to declare @BeforeAll and @AfterAll on non-static methods as well as on interface default methods. The "per-class" mode therefore also makes it possible to use @BeforeAll and @AfterAll methods in @Nested test classes.

But you've probably read that already and you are correct in thinking that making a field static will have the same effect as declaring the field as an instance variable and using @TestInstance(Lifecycle.PER_CLASS).

So, perhaps the answer to the question "how it could be useful in JUnit 5" is that using a @TestInstance ...

  • Is explicit about your intentions. It could be assumed that use of the static keyword was accidental whereas use of @TestInstance is less likely to be accidental or a result of thoughless copy-n-paste.
  • Delegates the responsibility for managing scope and lifecycle and clean up to the framework rather than having to remember to manage that yourself.

This annotation was introduced to reduce the number of objects created when running your unit tests.

Adding @TestInstance(TestInstance.Lifecycle.PER_CLASS) to your test class will avoid that a new instance of your class is created for every test in the class. This is particulary usefull when you have a lot of tests in the same test class and the instantiation of this class is expensive.

This annotation should be used with caution. All unit tests should be isolated and independent of eachother. If one of the tests changes the state od the test class then you should not use this feature.

Making your fields static to achieve the same effect is not a good idea. It will indeed reduce the number of objects created but they cannot be cleaned up when all tests in the test class are executed. This can cause problems when you have a giant test suite.