How can I have JUnit use a separate ClassLoader
for each test class it executes?
I am writing a JUnit TestRunner
for a library that sets a lot of static variables. I essentially want to reset all of these between each test class, without needing to know what all of them are. I do not want to be coupled to intimate knowledge of the framework, as whenever the library changes internally then my TestRunner
will break.
Before I go any further, I want to make absolutely clear that I really do want to do this.
Every other answer I can find on StackOverflow just says "don't do that," which isn't helpful. First person to answer with "static variables are dumb" wins a doughnut.
For JUnit 4, putting this annotation on the test class solved the problem. @FixMethodOrder(MethodSorters. JVM): Leaves the test methods in the order returned by the JVM. This order may vary from run to run.
Once parallel test execution property is enabled, the JUnit Jupiter engine will execute tests in parallel according to the provided configuration with declared synchronization mechanisms.
org.junitIf you allocate expensive external resources in a BeforeClass method you need to release them after all the tests in the class have run. Annotating a public static void method with @AfterClass causes that method to be run after all the tests in the class have been run.
In the end I wrote my own, loosely based on another Stack Overflow answer (which didn't work for me).
It's now on GitHub, and Maven Central. https://github.com/BinaryTweed/quarantining-test-runner
<dependency>
<groupId>com.binarytweed</groupId>
<artifactId>quarantining-test-runner</artifactId>
<version>0.0.1</version>
</dependency>
To use it annotate your test classes accordingly:
@RunWith(QuarantiningRunner.class)
@Quarantine({"com.binarytweed"})
public class MyIsolatedTest {
...
The linked answer didn't work for me as the test class itself needs to be loaded in a separate ClassLoader
, as then all the classes it references will use the same loader. Quarantining is inclusive (rather than exclusive) as you need the JUnit @Test
annotations to be loaded by the parent ClassLoader
, otherwise JUnit can't find any testable methods as it uses Class<Test>
as a key in a lookup map.
MyFaces has a TestPerClassLoaderRunner which is (despite its name) what you are looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With