What use is @TestInstance annotation in JUnit 5?

Mahozad picture Mahozad · Sep 28, 2018 · Viewed 15.3k times · Source

Can you give a simple explanation of @TestInstance annotation and how it is useful in JUnit 5?

I think we can achieve the same effect probably by making our fields static.

Answer

glytching picture glytching · Sep 28, 2018

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.