-
Notifications
You must be signed in to change notification settings - Fork 99
Add JUnit 4 to JUnit 5 migration precondition recipe #879
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
base: main
Are you sure you want to change the base?
Conversation
Implement a scanning recipe that identifies and marks JUnit 4 test classes eligible for migration to JUnit 5. This precondition recipe analyzes test classes to determine migratability based on: - Detection of supported vs. unsupported JUnit 4 rules and runners - Analysis of class inheritance hierarchies to ensure parent and child test classes use only supported features - Identification of @parameters annotations with class-type source attributes that cannot be migrated - Validation that all ancestors in the class hierarchy are also migratable The recipe marks only those test classes that can be successfully migrated, preventing build or test failures post-migration. This ensures fully automated, safe migrations by excluding classes with unsupported features from the migration process. This precondition recipe is designed to work with declarative JUnit 4 to JUnit 5 migration recipes, ensuring the migration recipe only modifies classes that are guaranteed to migrate successfully. Note: This recipe has been successfully used at Uber for large-scale JUnit 4 to JUnit 5 migrations. Upstreaming to benefit the broader OpenRewrite community. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
src/main/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5Precondition.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5Precondition.java
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5Precondition.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5Precondition.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5Precondition.java
Outdated
Show resolved
Hide resolved
src/test/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5PreconditionTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5PreconditionTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5PreconditionTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5PreconditionTest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/openrewrite/java/testing/junit5/JUnit4ToJunit5PreconditionTest.java
Outdated
Show resolved
Hide resolved
timtebeek
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for showcasing what you've done here @amishra-u ; Good to see how you're using this scanning precondition to limit results just to the whitelisted cases you know you can handle. Could be helpful for others looking to gradually adopt JUnit Jupiter still, with known cases not yet converted.
|
@timtebeek if everything looks good can you please merge it. |
| @Option(displayName = "Known migratable classes", | ||
| description = "A list of classes which are migratable. These are the classes for which recipes already exist. " + | ||
| "In practical scenarios, these are parent test classes for which we already have JUnit 5 versions.", | ||
| example = "org.example.MigratableBaseTestClass") | ||
| @Nullable Set<String> knownMigratableClasses; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some reservations about knownMigratableClasses, especially since that looks at a first glance to be a required field that ties the recipe/precondition strongly to a particular set of classes only expected to be present in a small set of (potentially large!) projects. By comparison the other options all more broadly applicable, but this one as a required options strongly limits where and how the precondition can be applied; would you agree there? Is there a way to put this particular requirement in a separate precondition that you'll maintain yourself? Or even use an existing recipe for that requirement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At Uber, we had many complex base test classes (around 10–20). Supporting all of their special cases via new or extended recipes was not practical, so we manually created JUnit 5 equivalents and added recipe to replace references of the original base classes.
These base classes contain shared test logic and are widely extended across the codebase. While micro-repos typically may include only one or two such classes, our monorepo grew into the double digits.
This option can be left empty and is therefore marked @nullable. Its values are inherently project-specific, so there is no sensible default for the open-source version of the recipe.
This recipe option worked well for us and could benefit others, but I’m happy to remove this option if it’s not a good fit for open source version.
Implement a scanning recipe that identifies and marks JUnit 4 test classes eligible for migration to JUnit 5. This precondition recipe analyzes test classes to determine migratability based on:
The recipe marks only those test classes that can be successfully migrated, preventing build or test failures post-migration. This ensures fully automated, safe migrations by excluding classes with unsupported features from the migration process.
This precondition recipe is designed to work with declarative JUnit 4 to JUnit 5 migration recipes, ensuring the migration recipe only modifies classes that are guaranteed to migrate successfully.
Note: This recipe has been successfully used at Uber for large-scale JUnit 4 to JUnit 5 migrations. Upstreaming to benefit the broader OpenRewrite community.
Checklist
🤖 Generated with Claude Code