quarkus icon indicating copy to clipboard operation
quarkus copied to clipboard

Upgrade to JUnit 6

Open gsmet opened this issue 2 weeks ago • 21 comments

  • Update to JUnit 6
  • Rename all quarkus-junit5* artifacts to quarkus-junit-jupiter* to avoid confusion and be consistent with JUnit naming
  • Put relocations in place
  • Some update recipes are prepared here: https://github.com/quarkusio/quarkus-updates/pull/410

Note that the assumption in this work is that junit-jupiter will mostly stay compatible and that they won't break everything. But I think it's a relatively fair assumption given how they handled the JUnit 4 -> JUnit 5 and the JUnit 5 -> JUnit 6 move.

gsmet avatar Dec 04 '25 18:12 gsmet

@gsmet this is what I came up with my investigation back then: 8781c2c (#50355)

Note that you also need to bump devtools/gradle/gradle/libs.versions.toml

gastaldi avatar Dec 05 '25 01:12 gastaldi

@gastaldi ah sorry, I totally missed you had started this work.

gsmet avatar Dec 05 '25 10:12 gsmet

/cc @cescoffier @geoand @Sanne @aloubyansky @gastaldi please check the approach described in the description as the renaming is a rather massive change and I would like to be sure we're all on the same page.

See https://groups.google.com/g/quarkus-dev/c/yUc9s5U4DbA

gsmet avatar Dec 05 '25 10:12 gsmet

Also /cc @holly-cummins @mkouba as you were involved in some of the testing infra.

gsmet avatar Dec 05 '25 10:12 gsmet

That's the plan I was +1 with :)

geoand avatar Dec 05 '25 10:12 geoand

🙈 The PR is closed and the preview is expired.

github-actions[bot] avatar Dec 05 '25 10:12 github-actions[bot]

I'm ok with this approach - but I wonder if you considered the alternative of introducing a new set of quarkus-junit6 artifacts rather than renaming? That would give people an easier path to upgrade decoupled from other changes, but I'm guessing this is only relevant if the assumption of super-smooth migration proves too optimistic.

This could also be useful if we had some semantic changes on our wishlist which we didn't dare do because of user update hassle.

(But I fully agree this is all unnecessary if it's a very simple drop-in change)

Sanne avatar Dec 05 '25 10:12 Sanne

I understand that JUnit6 is more like an evolution with minimal breaking changes and as such a good candidate for drop-in replacement. And the user has an option to go back to JUnit5 and it should work, more or less.

But I wonder if we should clarify the strategy for future releases. quarkus-junit-jupiter suggests that we will support a single version of JUnit which might be compatible with other versions (i.e. JUnit6 and JUnit5). But it does not suggest which version/s is/are actually supported. And that's probably fine but it requires some extra knowledge.

Also I don't have any numbers but I think that most users do not care about platform/jupiter/vintage, so quarkus-junit might be a better choice for the artifactId. Or maybe even quarkus-test?

Another question is - what if JUnit7 will be a "revolution", i.e. not a drop-in replacement? The artifactId remains the same, but Quarkus will silently drop support for older versions of JUnit?

mkouba avatar Dec 05 '25 11:12 mkouba

But I wonder if we should clarify the strategy for future releases. quarkus-junit-jupiter suggests that we will support a single version of JUnit which might be compatible with other versions (i.e. JUnit6 and JUnit5). But it does not suggest which version/s is/are actually supported. And that's probably fine but it requires some extra knowledge.

That's true. OTOH, the same could be said about Quarkus extensions, such as quarkus-hibernate.

Also I don't have any numbers but I think that most users do not care about platform/jupiter/vintage, so quarkus-junit might be a better choice for the artifactId. Or maybe even quarkus-test?

quarkus-junit looks nice.

aloubyansky avatar Dec 05 '25 12:12 aloubyansky

We could go with quarkus-junit. My problem with this is: what if they introduce a brand new version that breaks the compatibility entirely and we want to support bother versions at the same time.

Now I'm not sold with the names, we can adjust but it's not really easy to find something that is future proof given we have no idea what the future will be.

gsmet avatar Dec 05 '25 12:12 gsmet

As for quarkus-junit6, why not but the thing is that I really don't want to support both JUnit 5 and 6 given they are very very similar and as @mkouba said more an evolution. So if we did that, I think I would add some relocations to rewrite junit5 to junit6 anyway and keep only one version.

gsmet avatar Dec 05 '25 12:12 gsmet

I really don't want to support both JUnit 5 and 6

I couldn't agree more. We should only support one

geoand avatar Dec 05 '25 12:12 geoand

We could go with quarkus-junit. My problem with this is: what if they introduce a brand new version that breaks the compatibility entirely and we want to support bother versions at the same time.

Like a replacement for Jupiter? :thinking: That would mean a new programming model/extension model and I don't think we will be able to support multiple extension models easily...

Now I'm not sold with the names, we can adjust but it's not really easy to find something that is future proof given we have no idea what the future will be.

:100:

mkouba avatar Dec 05 '25 12:12 mkouba

Like a replacement for Jupiter? 🤔 That would mean a new programming model/extension model and I don't think we will be able to support multiple extension models easily...

Well at some point we had a JUnit 4 artifact IIRC. If they push a brand new version of JUnit that breaks everything, we will probably need new artifacts and yes a brand new implementation. And we might want to support both models for a while. Now, we could decide to rename the old ones to a disctinctive names and keep quarkus-junit for the latest.

I'm fine with moving to quarkus-junit. Let me know if it all works for you... because given it's a simplification, it will be annoying to rename it afterwards.

gsmet avatar Dec 05 '25 13:12 gsmet

I'm fine with moving to quarkus-junit

Fine with me as well

geoand avatar Dec 05 '25 13:12 geoand

No objections, but thinking ahead how about quarkus-test as @mkouba suggested earlier? That would save us the hassle of renaming again if Junit brand is renamed to something else

gastaldi avatar Dec 05 '25 13:12 gastaldi

No objections, but thinking ahead how about quarkus-test as @mkouba suggested earlier? That would save us the hassle of renaming again if Junit brand is renamed to something else

That seems too generic to me; it doesn't give people enough information about what's inside. In particular, it's not obvious from the dependency name that you wouldn't need JUnit on your classpath, because this is giving you JUnit.

It would also rule out some future in which we decide we don't have enough work and want to support both JUnit and a cool new challenger testing framework. It would kind of work if we switched from JUnit to CoolNewChallengerTest, but I'm not sure we'd want the name to stay the same if we did such a massive breaking change.

holly-cummins avatar Dec 05 '25 13:12 holly-cummins

We also could create something on our own and name it quarkus-test.

aloubyansky avatar Dec 05 '25 14:12 aloubyansky

Obviously, the only constant in technology is change, but given what we've seen in the past few years, I don't think that many people are asking for / and no one I know of is working on a new unit test framework in Java - JUnit has won, and rightly so, as it is awesome. Moreover, I don't envision that JUnit itself will introduce some massive programming model change - it uses what most of the enterprise Java community has settled on, i.e., an annotation-based model based on a well-defined lifecycle and by all accounts, users are happy with it.

I don't see the JUnit 4 vs TestNG vs Spock situation repeating itself any time soon (and I'd be willing to put my money where my mouth is on this :)).

Calling the extension quarkus-junit seems like the most pragmatic option to me as it conveys the functionality of the dependency, and if JUnit 7 comes along at some point and has some breaking changes - so be it, we and users deal with analogous situations in other extensions all the time.

geoand avatar Dec 05 '25 14:12 geoand

Yeah, I'm -1 for quarkus-test and I'm fine with quarkus-junit.

If nobody objects by Monday evening, I will go do that on Tuesday.

gsmet avatar Dec 05 '25 14:12 gsmet

+1 for quarkus-junit.

The plan looks good to me! Thanks!

cescoffier avatar Dec 09 '25 07:12 cescoffier

Status for workflow Quarkus Documentation CI

This is the status report for running Quarkus Documentation CI on commit b7841bc199b917c3cc21caf5b6854b18efa1d464.

:white_check_mark: The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

[!WARNING] There are other workflow runs running, you probably need to wait for their status before merging.

quarkus-bot[bot] avatar Dec 11 '25 21:12 quarkus-bot[bot]

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit b7841bc199b917c3cc21caf5b6854b18efa1d464.

Failing Jobs

Status Name Step Failures Logs Raw logs Build scan
:heavy_check_mark: JVM Tests - JDK 17 Logs Raw logs :mag:
:heavy_check_mark: JVM Tests - JDK 21 Logs Raw logs :mag:
:heavy_check_mark: JVM Tests - JDK 21 Semeru Logs Raw logs :mag:
:heavy_check_mark: JVM Tests - JDK 25 Logs Raw logs :mag:
:x: JVM Tests - JDK 17 Windows Build Failures Logs Raw logs :mag:

You can consult the Develocity build scans.

Failures

:gear: JVM Tests - JDK 17 Windows #

- Failing: devtools/gradle/gradle-application-plugin 

:package: devtools/gradle/gradle-application-plugin

:x: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:3.6.2:exec (gradle) on project io.quarkus.gradle.plugin: Command execution failed.


Flaky tests - Develocity

:gear: JVM Tests - JDK 21 Semeru

:package: extensions/micrometer-opentelemetry/deployment

:x: io.quarkus.micrometer.opentelemetry.deployment.compatibility.MicrometerTimedInterceptorTest.testTimeMethod_UniFailed - History

  • Stream has no elements - java.lang.IllegalArgumentException
java.lang.IllegalArgumentException: Stream has no elements
	at io.quarkus.micrometer.opentelemetry.deployment.common.MetricDataFilter.lastReadingDataPoint(MetricDataFilter.java:236)
	at io.quarkus.micrometer.opentelemetry.deployment.compatibility.MicrometerTimedInterceptorTest.testTimeMethod_UniFailed(MicrometerTimedInterceptorTest.java:202)

:gear: MicroProfile TCKs Tests

:package: tcks/microprofile-lra

:x: org.eclipse.microprofile.lra.tck.TckRecoveryTests.testCancelWhenParticipantIsUnavailable - History

  • Expecting the metric Compensated callback was called Expected: a value equal to or greater than <1> but: <0> was less than <1> - java.lang.AssertionError
java.lang.AssertionError: 
Expecting the metric Compensated callback was called
Expected: a value equal to or greater than <1>
     but: <0> was less than <1>
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.eclipse.microprofile.lra.tck.TckRecoveryTests.assertMetricCallbackCalled(TckRecoveryTests.java:210)
	at org.eclipse.microprofile.lra.tck.TckRecoveryTests.testCancelWhenParticipantIsUnavailable(TckRecoveryTests.java:195)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

quarkus-bot[bot] avatar Dec 12 '25 01:12 quarkus-bot[bot]

@geoand @mkouba @cescoffier @aloubyansky @gastaldi this is now ready. Let's not wait too long before merging as conflicts might be fun to fix...

gsmet avatar Dec 12 '25 10:12 gsmet