Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public void junit5Suite() throws Exception {
.verifyTextInLog("Running pkg.domain.AxTest")
.assertThatLogLine(containsString("Running pkg.domain.BxTest"), equalTo(0));

TestFile xmlReportFile = outputValidator.getSurefireReportsXmlFile("TEST-pkg.JUnit5Tests.xml");
TestFile xmlReportFile = outputValidator.getSurefireReportsXmlFile("TEST-pkg.domain.AxTest.xml");
xmlReportFile.assertFileExists();

Source source = Input.fromFile(xmlReportFile.getFile()).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,29 @@ private TestIdentifier findTopParent(TestIdentifier testIdentifier) {
// use deprecated method
testPlan.getTestIdentifier(
testIdentifier.getParentIdObject().get().toString());
return !parent.getParentIdObject().isPresent() ? testIdentifier : findTopParent(parent);
if (!parent.getParentIdObject().isPresent()) {
return testIdentifier;
}
// Stop traversing at engine boundaries. When a test runs inside a Suite,
// the hierarchy contains a nested engine (e.g., junit-jupiter under junit-platform-suite).
// Without this check, tests would be incorrectly attributed to the Suite class
// instead of their actual test class.
if (isEngineIdentifier(parent)) {
return testIdentifier;
}
return findTopParent(parent);
}

private static boolean isEngineIdentifier(TestIdentifier testIdentifier) {
String uniqueId = testIdentifier.getUniqueId();
int lastOpen = uniqueId.lastIndexOf('[');
if (lastOpen >= 0) {
int colon = uniqueId.indexOf(':', lastOpen);
if (colon > lastOpen) {
return "engine".equals(uniqueId.substring(lastOpen + 1, colon));
}
}
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,62 @@ public void displayNamesIgnoredInReport() throws NoSuchMethodException {
assertEquals("some display name", value.getNameText());
}

@Test
public void notifiedWithActualTestClassNameWhenRunInsideSuite() throws Exception {
// Build a Suite hierarchy: SuiteEngine -> SuiteClass -> JupiterEngine -> TestClass -> method
// This simulates @Suite @SelectPackages("...") running tests from another class.
EngineDescriptor suiteEngine =
new EngineDescriptor(UniqueId.forEngine("junit-platform-suite"), "JUnit Platform Suite");

TestDescriptor suiteClass = new ClassTestDescriptor(
suiteEngine.getUniqueId().append("suite", MySuiteClass.class.getName()),
MySuiteClass.class,
new DefaultJupiterConfiguration(CONFIG_PARAMS, OUTPUT_DIRECTORY));
suiteEngine.addChild(suiteClass);

TestDescriptor jupiterEngine =
new AbstractTestDescriptor(
suiteClass.getUniqueId().append("engine", "junit-jupiter"), "JUnit Jupiter") {
@Override
public Type getType() {
return Type.CONTAINER;
}
};
suiteClass.addChild(jupiterEngine);

TestDescriptor testClass = new ClassTestDescriptor(
jupiterEngine.getUniqueId().append("class", MyTestClass.class.getName()),
MyTestClass.class,
new DefaultJupiterConfiguration(CONFIG_PARAMS, OUTPUT_DIRECTORY));
jupiterEngine.addChild(testClass);

TestDescriptor method = new TestMethodTestDescriptor(
testClass.getUniqueId().append("method", MY_TEST_METHOD_NAME),
MyTestClass.class,
MyTestClass.class.getDeclaredMethod(MY_TEST_METHOD_NAME),
Collections::emptyList,
new DefaultJupiterConfiguration(CONFIG_PARAMS, OUTPUT_DIRECTORY));
testClass.addChild(method);

TestPlan plan = TestPlan.from(false, singletonList(suiteEngine), CONFIG_PARAMS, OUTPUT_DIRECTORY);
adapter.testPlanExecutionStarted(plan);

adapter.executionStarted(TestIdentifier.from(suiteEngine));
adapter.executionStarted(TestIdentifier.from(suiteClass));
adapter.executionStarted(TestIdentifier.from(jupiterEngine));
adapter.executionStarted(TestIdentifier.from(testClass));
adapter.executionStarted(TestIdentifier.from(method));

ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
adapter.executionFinished(TestIdentifier.from(method), failed(new AssertionError("fail")));
verify(listener).testFailed(entryCaptor.capture());

ReportEntry entry = entryCaptor.getValue();
// The source name must be the actual test class, not the Suite class
assertEquals(MyTestClass.class.getName(), entry.getSourceName());
assertEquals(MY_TEST_METHOD_NAME, entry.getName());
}

private static TestIdentifier newMethodIdentifier() throws Exception {
return TestIdentifier.from(newMethodDescriptor());
}
Expand Down Expand Up @@ -720,6 +776,8 @@ void myTestMethod(String foo) {}
void myNamedTestMethod() {}
}

private static class MySuiteClass {}

static class TestMethodTestDescriptorWithDisplayName extends AbstractTestDescriptor {
private TestMethodTestDescriptorWithDisplayName(
UniqueId uniqueId, Class<?> testClass, Method testMethod, String displayName) {
Expand Down
Loading