Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add @TestInstance(TestInstance.Lifecycle.PER_CLASS) where required #14

Open
Philzen opened this issue Jun 14, 2024 · 0 comments
Open

Add @TestInstance(TestInstance.Lifecycle.PER_CLASS) where required #14

Philzen opened this issue Jun 14, 2024 · 0 comments
Assignees
Labels
Feature New feature or request must-have

Comments

@Philzen
Copy link
Owner

Philzen commented Jun 14, 2024

TestNG instantiates test classes once and then runs all contained test methods on the same instance, while JUnit by default instantiates a fresh object for each test method:

In order to allow individual test methods to be executed in isolation and to avoid unexpected side effects due to mutable test instance state, JUnit creates a new instance of each test class before executing each test method (see Definitions). This "per-method" test instance lifecycle is the default behavior in JUnit Jupiter and is analogous to all previous versions of JUnit.

This behavior can be changed to mimic that of TestNG by putting the @TestInstance(TestInstance.Lifecycle.PER_CLASS) annotation on the class-level.


https://github.com/MBoegers/migrate-testngtojupiter-rewrite/blob/main/src/main/java/io/github/mboegers/openrewrite/testngtojupiter/AddTestLifecyleToJUnitTests.java can serve as a nice starting point here.


Important: It is only applied to the scope it is annotating, that means every nested class will still be instantiated per-method unless also annotated with @TestInstance(TestInstance.Lifecycle.PER_CLASS). The annotation will be absolutely mandatory on a nested class if it contains @BeforeAll / @AfterAll annotations, otherwise any tests in that class won't be executed and the Junit runner will fail with:

org.junit.platform.commons.JUnitException: @BeforeAll method 'void org.philzen.oss.research.JupiterNestedBeforeAllTest$Topic.beforeAll()' must be static unless the test class is annotated with @testinstance(Lifecycle.PER_CLASS).


It may be considered to skip the adding the annotation onto a class if all of the following is true:

  • all methods in it are @Tests
  • there is no constructor

However, in certain fringe cases this may not be enough, as a (badly written, however possible) test could refer to some global state (not only static state in other classes, but also System properties, etc.). So it is probably the safest to apply the migration everywhere.

@Philzen Philzen moved this to Ready in TestNG → Jupiter Jun 14, 2024
@Philzen Philzen added Feature New feature or request must-have labels Jun 14, 2024
@Philzen Philzen self-assigned this Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature or request must-have
Projects
Status: Ready
Development

No branches or pull requests

1 participant