You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2025-04-22-test-classloading-rewrite.adoc
+10-7
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,10 @@ author: hcummins
10
10
11
11
The internals of Quarkus test classloading have been rewritten in 3.22.
12
12
In particular, how `@QuarkusTest` test classes are loaded is changing.
13
+
Other test extensions haven't changed, nor has dev mode and production mode classloading.
14
+
This change should make Quarkus testing work better, and it allowed us to fix a pile of longstanding bugs.
15
+
However, it did introduce a few bugs we know about, and most likely also some bugs we don't yet know about.
16
+
We're keen to get feedback from the community so that we can get fixing.
13
17
14
18
== Why?
15
19
@@ -21,9 +25,9 @@ However, some use cases didn't work. Tests using advanced JUnit features like `@
21
25
22
26
While Quarkus extensions can do all sorts of marvellous bytecode manipulation to improve the developer experience, they cannot manipulate test classes with the same freedom that they do normal application classes.
23
27
24
-
Over time, test-related defects were building up that couldn't be changed without a fundamental rewrite of test classloading. The Quarkus test code itself was also growing ever-more complex as it tried to work around various JUnit edge cases. Moving test instances from one classloader to another involved serializing and deserialization, which is harder to implement on newer JVM versions with tighter class security. For example, Quarkus used to use XStream as the serialization provider, but XStream stopped working in Java 17.
28
+
Over time, test-related defects were building up that couldn't be changed without a fundamental rewrite of test classloading. The Quarkus test code itself was also growing ever-more complex as it tried to work around various JUnit edge cases. Moving test instances from one classloader to another involved serializing and deserialization, which is harder to implement on newer JVM versions with tighter class security. For example, Quarkus used to use XStream as the serialization provider, but XStream no longer works with Java 17 and higher, because of reflection restrictions in the newer JVMs.
25
29
26
-
What if, instead, tests were simply run in the same classloader used to to load them?
30
+
What if, instead, Quarkus tests were simply run in the same classloader used to to load them?
27
31
28
32
== What you need to do
29
33
@@ -33,11 +37,6 @@ Hopefully, nothing.
33
37
One of the goals of this change was that the rewrite didn't touch any tests in our test suite, to make sure they'd all continue working without updates.
34
38
In practice, there have been a few hiccups and we've discovered some edge cases in the broader ecosystem.
35
39
36
-
=== Dropped support
37
-
38
-
- *`@TestProfile` on `@Nested` tests.* Mixing different test profiles and test resources on `@Nested` tests is no longer supported. By definition, every `@TestProfile` must get its own Quarkus application and classloader. Having multiple classloaders execute one test isn't compatible with loading the test with the classloader used to run it.
39
-
- *Version 2.x of the Maven Surefire plugin*. Versions below 3.x of the Maven Surefire plugin will no longer work with `@QuarkusTest`. Version 3 of the Surefire plugin was released in 2023, so version 2 is now rather old.
40
-
41
40
=== Known regressions
42
41
43
42
- *Dev services start in the discovery phase*. Quarkus Dev Services are currently started during the augmentation phase. With the new design, all augmentation happens at the beginning of the test run. If several test classes with different Dev Service configuration are augmented before any tests are run, multiple differently-configured Dev Services may be running at the same time. This can cause port conflicts and cross-talk on configuration values. We're hoping to have a https://github.com/quarkusio/quarkus/issues/45785[fix] for this in the next release. As a workaround, splitting conflicting tests into separate projects should fix symptoms.
@@ -49,6 +48,10 @@ In practice, there have been a few hiccups and we've discovered some edge cases
49
48
- *Test order change*. As part of the rewrite, the execution order of some tests has swapped around. Of course, we all know tests should not depend on execution order if they don't set an order explicitly. However, it's easy to not notice that a test requires a certain order... until the order changes. We discovered some tests in our own suite that were sensitive to the execution order, and other people may make similar discoveries.
50
49
- *Test timing change*. We also discovered that the rewrite exposed some timing issues in tests. Because classloading is frontloaded at the beginning of the test run, rather than between test executions, there's less time for asynchronous operations to finish between tests. For example, there may no longer be time for external state to 'reset' before the next test starts. This might expose some heisenbugs in test suites.
51
50
51
+
=== Dropped support
52
+
53
+
- *`@TestProfile` on `@Nested` tests.* Mixing different test profiles and test resources on `@Nested` tests is no longer supported. By definition, every `@TestProfile` must get its own Quarkus application and classloader. Having multiple classloaders execute one test isn't compatible with loading the test with the classloader used to run it.
54
+
- *Version 2.x of the Maven Surefire plugin*. Versions below 3.x of the Maven Surefire plugin will no longer work with `@QuarkusTest`. Version 3 of the Surefire plugin was released in 2023, so version 2 is now rather old.
0 commit comments