-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Currently, JUnit 5 requires tests to specify a DisplayNameGenerator either:
-
Globally via the junit.jupiter.displayname.generator system property.
-
On a per-class basis using @DisplayNameGeneration(SomeGenerator.class).
This request proposes allowing test classes to implement or extend DisplayNameGenerator, enabling a more natural and scalable way to define test naming conventions, particularly when using a shared parent class for tests.
Use Case
In large test suites, it's common to have a base test class that all test classes inherit from. This base class often includes shared configuration and behavior. It would be useful if test classes could inherit a DisplayNameGenerator from the base class, rather than requiring explicit annotations on each test class.
For example:
import org.junit.jupiter.api.DisplayNameGenerator;
import java.lang.reflect.Method;
public class FetchTestSuite implements DisplayNameGenerator {
@Override
public String generateDisplayNameForClass(Class<?> testClass) {
return "Suite: " + testClass.getSimpleName();
}
@Override
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
return "Test: " + testMethod.getName().replace("_", " ");
}
}
Any test class extending FetchTestSuite would automatically inherit the display name generation logic:
import org.junit.jupiter.api.Test;
public class MyTest extends FetchTestSuite {
@Test
void some_test_case() {
// Expected display name: "Test: some test case"
}
}
If a subclass wants a different naming strategy, it can simply override the methods:
public class MyTest extends FetchTestSuite {
@Override
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
return "🔹 Custom Test: " + testMethod.getName();
}
}
Current Workarounds
Currently, to achieve this behavior, we must:
- Manually annotate every test class with @DisplayNameGeneration(FetchTestSuite.class).
- Use an extension that applies System.setProperty("junit.jupiter.displayname.generator", SomeGenerator.class.getName()) before tests run (which is an indirect solution).
Proposed Solution
JUnit should automatically check whether a test class implements or extends DisplayNameGenerator, and if so, use it as the display name generator instead of requiring an annotation.
Suggested logic:
If a test class is annotated with @DisplayNameGeneration, use the specified generator, else, if the test class implements DisplayNameGenerator, use it. else, fallback to the default behavior.
Benefits
✅ Less Boilerplate – No need for redundant annotations on every test class.
✅ Follows Normal Java Inheritance – Subclasses can override naming logic as needed.
✅ More Flexible and Scalable – Large test suites with shared behavior benefit from a centralized naming strategy.
✅ Backwards Compatible – This change does not break existing behavior unless the author has already had a test class implement DisplayNameGenerator, at which point they're likely to want this enhancement to allow them to remove extra code.