diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire2117XmlReportingNestedIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire2117XmlReportingNestedIT.java new file mode 100644 index 0000000000..83dae61bc1 --- /dev/null +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire2117XmlReportingNestedIT.java @@ -0,0 +1,98 @@ +package org.apache.maven.surefire.its.jiras; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.util.Arrays; + +import org.apache.maven.surefire.its.fixture.OutputValidator; +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +/** + * Integration Test for SUREFIRE-2117 + */ +@RunWith( Parameterized.class ) +@SuppressWarnings( "checkstyle:magicnumber" ) +public class Surefire2117XmlReportingNestedIT extends SurefireJUnit4IntegrationTestCase +{ + @Parameter + @SuppressWarnings( "checkstyle:visibilitymodifier" ) + public String jupiterVersion; + + @Parameters( name = "{0}" ) + public static Iterable junitJupiterVersions() + { + return Arrays.asList( "5.2.0", "5.8.2", "5.9.1" ); + } + + @Test + public void testXmlReport() + { + OutputValidator validator = unpack( "surefire-2117-xml-reporting-nested", "-" + jupiterVersion ) + .sysProp( "junit5.version", jupiterVersion ) + .executeTest() + .verifyErrorFree( 9 ); + + validator.getSurefireReportsFile( "TEST-jira2117.NestedJupiterTest$A.xml", UTF_8 ) + .assertContainsText( " + + + + 4.0.0 + + org.apache.maven.plugins.surefire + surefire-2117-xml-reporting-nested + 1.0 + Test for: JUnit5Xml30StatelessReporter and Nested + + + 1.8 + 1.8 + UTF-8 + + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit5.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit5.version} + test + + + + + + + maven-compiler-plugin + 3.8.0 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + 1.0C + true + + false + 3.0 + false + true + true + true + + + false + UTF-8 + false + + + false + false + true + true + + + + + + + diff --git a/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedDisplayNameTest.java b/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedDisplayNameTest.java new file mode 100644 index 0000000000..7789ec839f --- /dev/null +++ b/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedDisplayNameTest.java @@ -0,0 +1,69 @@ +package jira2117; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +@DisplayName( "Display name of the main test class" ) +class NestedDisplayNameTest +{ + @Nested + @DisplayName( "Display name of level 1 nested class A" ) + class A + { + @Test + void level1_test_without_display_name() + { + } + + @Test + @DisplayName( "Display name of level 1 test method" ) + void level1_test_with_display_name() + { + } + } + + @Nested + @DisplayName( "Display name of level 1 nested class B" ) + class B + { + @Nested + @DisplayName( "Display name of level 2 nested class C" ) + class C + { + @Test + @DisplayName( "Display name of non-parameterized level 2 test method" ) + void level2_test_nonparameterized() + { + } + + @ParameterizedTest + @ValueSource(strings = {"paramValue1", "paramValue2"}) + @DisplayName( "Display name of parameterized level 2 test method" ) + void level2_test_parameterized(String paramValue) + { + } + } + } +} diff --git a/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedJupiterTest.java b/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedJupiterTest.java new file mode 100644 index 0000000000..7f1db77df5 --- /dev/null +++ b/surefire-its/src/test/resources/surefire-2117-xml-reporting-nested/src/test/java/jira2117/NestedJupiterTest.java @@ -0,0 +1,56 @@ +package jira2117; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +class NestedJupiterTest +{ + @Nested + class A + { + @Test + void level1_test() + { + } + } + + @Nested + class B + { + @Nested + class C + { + @Test + void level2_test_nonparameterized() + { + } + + @ParameterizedTest + @ValueSource(strings = {"paramValue1", "paramValue2"}) + void level2_test_parameterized(String paramValue) + { + } + } + } +} diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java index 7272f36286..3e4e605e53 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java @@ -21,10 +21,13 @@ import static java.util.Collections.emptyMap; import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps; import static org.apache.maven.surefire.shared.lang3.StringUtils.isNotBlank; import static org.junit.platform.engine.TestExecutionResult.Status.FAILED; +import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -356,10 +359,20 @@ private String[] toClassMethodName( TestIdentifier testIdentifier ) } else if ( testSource.filter( ClassSource.class::isInstance ).isPresent() ) { + List parentClassDisplays = + collectAllTestIdentifiersInHierarchy( testIdentifier ) + .filter( identifier -> identifier.getSource().filter( ClassSource.class::isInstance ).isPresent() ) + .map( TestIdentifier::getDisplayName ) + .collect( toList() ); + + Collections.reverse( parentClassDisplays ); + String classDisplay = Stream.concat( parentClassDisplays.stream(), Stream.of( display ) ) + .collect( joining( " " ) ); + ClassSource classSource = testSource.map( ClassSource.class::cast ).get(); String className = classSource.getClassName(); String simpleClassName = className.substring( 1 + className.lastIndexOf( '.' ) ); - String source = display.equals( simpleClassName ) ? className : display; + String source = classDisplay.replace( ' ', '$' ).equals( simpleClassName ) ? className : classDisplay; return new String[] {className, source, null, null}; } else diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java index f734bab115..9e376cc065 100644 --- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java @@ -75,6 +75,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.platform.launcher.EngineFilter; import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.TestIdentifier; @@ -452,6 +453,40 @@ public void runDisplayNameTest() throws Exception assertEquals( "73$71 ✔", reportEntries.get( 0 ).getNameText() ); } + @Test + public void runNestingTest() throws Exception + { + Launcher launcher = LauncherFactory.create(); + ProviderParameters parameters = providerParametersMock(); + JUnitPlatformProvider provider = new JUnitPlatformProvider( parameters, launcher ); + + TestReportListener listener = mock( TestReportListener.class ); + ArgumentCaptor entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + RunListenerAdapter adapter = new RunListenerAdapter( listener ); + adapter.setRunMode( NORMAL_RUN ); + + launcher.registerTestExecutionListeners( adapter ); + + invokeProvider( provider, NestingTest.class ); + + verify( listener, times( 2 ) ).testStarting( entryCaptor.capture() ); + List reportEntries = entryCaptor.getAllValues(); + + assertEquals( 2, reportEntries.size() ); + + assertEquals( NestingTest.Level1NestedTest.class.getName(), + reportEntries.get( 0 ).getSourceName() ); + assertNull( reportEntries.get( 0 ).getSourceText() ); + assertEquals( "level1test", reportEntries.get( 0 ).getName() ); + assertNull( reportEntries.get( 0 ).getNameText() ); + + assertEquals( NestingTest.Level1NestedTest.Level2NestedTest.class.getName(), + reportEntries.get( 1 ).getSourceName() ); + assertNull( reportEntries.get( 1 ).getSourceText() ); + assertEquals( "level2test", reportEntries.get( 1 ).getName() ); + assertNull( reportEntries.get( 1 ).getNameText() ); + } + @Test public void detectErroredParameterized() throws Exception @@ -1427,6 +1462,27 @@ void test1() } } + static class NestingTest + { + @Nested + class Level1NestedTest + { + @org.junit.jupiter.api.Test + void level1test() + { + } + + @Nested + class Level2NestedTest + { + @org.junit.jupiter.api.Test + void level2test() + { + } + } + } + } + static class FailingBeforeAllJupiterTest {