This is an automated email from the ASF dual-hosted git repository. tibordigana pushed a commit to branch 1330 in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit 07778b7e342a87ac9810494c9f6342b3135178ec Author: Tibor17 <tibordig...@apache.org> AuthorDate: Fri Apr 13 23:51:33 2018 +0200 junit5 --- .../plugin/surefire/AbstractSurefireMojo.java | 46 ++- pom.xml | 7 +- surefire-its/pom.xml | 23 +- .../maven/surefire/its/JUnit4VersionsIT.java | 74 +++-- .../org/apache/maven/surefire/its/JUnit5IT.java} | 50 +--- .../maven/surefire/its/JUnitPlatformIT.java} | 48 +-- .../apache/maven/surefire/its/JUnitVersion.java | 80 +++++ .../resources/{junit4 => junit-platform}/pom.xml | 55 ++-- .../src/test/java/junitplatform}/BasicTest.java | 30 +- surefire-its/src/test/resources/junit4/pom.xml | 141 +++++++-- .../junit4/src/test/java/junit4/BasicTest.java | 4 +- .../BasicTest.java => junit5/JUnit5Test.java} | 35 ++- surefire-its/src/test/resources/junit5/pom.xml | 77 +++++ .../src/test/java/junit5/JUnit4Test.java} | 19 +- .../src/test/java/junit5/JUnit5Test.java} | 36 +-- surefire-providers/pom.xml | 1 + surefire-providers/surefire-junit-platform/pom.xml | 167 +++++++++++ .../junitplatform/JUnitPlatformProvider.java | 202 +++++++++++++ .../surefire/junitplatform/RunListenerAdapter.java | 150 ++++++++++ .../junitplatform/TestPlanScannerFilter.java | 64 ++++ ...che.maven.surefire.providerapi.SurefireProvider | 1 + .../junitplatform/JUnitPlatformProviderTests.java | 325 +++++++++++++++++++++ .../junitplatform/RunListenerAdapterTests.java | 252 ++++++++++++++++ .../junitplatform/TestPlanScannerFilterTests.java | 190 ++++++++++++ 24 files changed, 1837 insertions(+), 240 deletions(-) diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java index 34f805a..dcfabae 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java @@ -1024,6 +1024,7 @@ public abstract class AbstractSurefireMojo new TestNgProviderInfo( getTestNgArtifact() ), new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ), new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ), + new JUnitPlattformProviderInfo( getJunitArtifact() ), new JUnit3ProviderInfo() ) .resolve(); } @@ -1540,7 +1541,17 @@ public abstract class AbstractSurefireMojo return dependencyResolver.isWithinVersionSpec( artifact, "[4.0,)" ); } - static boolean isForkModeNever( String forkMode ) + private boolean isJunitJupiter( Artifact artifact ) + { + return dependencyResolver.isWithinVersionSpec( artifact, "[5.0.0,)" ); + } + + private boolean isJunitVintage( Artifact artifact ) + { + return dependencyResolver.isWithinVersionSpec( artifact, "[4.12.0,5.0.0)" ); + } + + private static boolean isForkModeNever( String forkMode ) { return FORK_NEVER.equals( forkMode ); } @@ -2873,6 +2884,39 @@ public abstract class AbstractSurefireMojo } + final class JUnitPlattformProviderInfo + implements ProviderInfo + { + private final Artifact junitArtifact; + + JUnitPlattformProviderInfo( Artifact junitArtifact ) + { + this.junitArtifact = junitArtifact; + } + + @Nonnull public String getProviderName() + { + return "org.apache.maven.surefire.junitplatform.JUnitPlatformProvider"; + } + + public boolean isApplicable() + { + return isJunitJupiter( junitArtifact ) || isJunitVintage( junitArtifact ); + } + + public void addProviderProperties() throws MojoExecutionException + { + } + + public Classpath getProviderClasspath() + throws ArtifactResolutionException, ArtifactNotFoundException + { + return dependencyResolver.getProviderClasspath( "surefire-junit-platform", + surefireBooterArtifact.getBaseVersion(), + null ); + } + } + final class JUnitCoreProviderInfo implements ProviderInfo { diff --git a/pom.xml b/pom.xml index 5fdefd4..96a75a4 100644 --- a/pom.xml +++ b/pom.xml @@ -97,8 +97,9 @@ <maven.site.path>surefire-archives/surefire-LATEST</maven.site.path> <!-- Override with Jigsaw JRE 9 --> <jdk.home>${java.home}/..</jdk.home> - <maven.compiler.testSource>1.6</maven.compiler.testSource> - <maven.compiler.testTarget>1.6</maven.compiler.testTarget> + <javaVersion>6</javaVersion> + <maven.compiler.testSource>1.${javaVersion}</maven.compiler.testSource> + <maven.compiler.testTarget>1.${javaVersion}</maven.compiler.testTarget> <jvm.args.tests>-server -XX:+UseG1GC -Xms128m -Xmx144m -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true</jvm.args.tests> </properties> @@ -419,6 +420,7 @@ <excludeDependencies> <param>org.codehaus.plexus:plexus-java</param> <param>org.ow2.asm:asm</param> + <param>org.junit.platform:junit-platform-commons</param> </excludeDependencies> <ignores> <param>org.objectweb.asm.*</param> @@ -550,6 +552,7 @@ <excludes> <exclude>org.codehaus.plexus:plexus-java</exclude> <exclude>org.ow2.asm:asm</exclude> + <exclude>org.junit.platform:junit-platform-commons</exclude> </excludes> </enforceBytecodeVersion> </rules> diff --git a/surefire-its/pom.xml b/surefire-its/pom.xml index 88a4870..d4c7df4 100644 --- a/surefire-its/pom.xml +++ b/surefire-its/pom.xml @@ -104,7 +104,9 @@ <forkMode>once</forkMode> <argLine>-server -Xmx64m -XX:+UseG1GC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.awt.headless=true</argLine> <includes> - <include>org/apache/**/*IT*.java</include> + <include>org/apache/**/JUnit4VersionsIT.java</include> + <include>org/apache/**/JUnit5IT.java</include> + <include>org/apache/**/JUnitPlatformIT.java</include> </includes> <!-- Pass current surefire version to the main suite so that it --> <!-- can forward to all integration test projects. SUREFIRE-513 --> @@ -143,25 +145,6 @@ </executions> </plugin> <plugin> - <artifactId>maven-enforcer-plugin</artifactId> - <executions> - <execution> - <id>require-maven-2.1.0</id> - <goals> - <goal>enforce</goal> - </goals> - <configuration> - <rules> - <requireMavenVersion> - <!-- Some plugin features require a recent Maven runtime to work (e.g. SystemPropertiesTest) --> - <version>[2.1.0,)</version> - </requireMavenVersion> - </rules> - </configuration> - </execution> - </executions> - </plugin> - <plugin> <artifactId>maven-jar-plugin</artifactId> <!-- todo dont skip since of failsafe:2.19 internal use if having src/main/java/... --> <configuration> diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit4VersionsIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit4VersionsIT.java index 8dd8f0c..c391964 100644 --- a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit4VersionsIT.java +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit4VersionsIT.java @@ -19,7 +19,6 @@ package org.apache.maven.surefire.its; * under the License. */ -import java.util.Arrays; import java.util.Collection; import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; @@ -29,8 +28,28 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; +import static java.util.Arrays.asList; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_10; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_11; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_12; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_8; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_8_1; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_8_2; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_9; import static org.junit.runners.Parameterized.*; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_0; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_1; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_2; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_3; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_3_1; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_4; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_5; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_6; +import static org.apache.maven.surefire.its.JUnitVersion.JUNIT_4_7; +import static org.apache.maven.surefire.its.JUnitVersion.JUPITER_5_1_1; +import static org.apache.maven.surefire.its.JUnitVersion.VINTAGE_5_1_1; + /** * Basic suite test using all known versions of JUnit 4.x * @@ -44,44 +63,41 @@ public class JUnit4VersionsIT @Parameters( name = "{index}: JUnit {0}" ) public static Collection<Object[]> junitVersions() { - return Arrays.asList( new Object[][] { - { "4.0" }, - { "4.1" }, - { "4.2" }, - { "4.3" }, - { "4.3.1" }, - { "4.4" }, - { "4.5" }, - { "4.6" }, - { "4.7" }, - { "4.8" }, - { "4.8.1" }, - { "4.8.2" }, - { "4.9" }, - { "4.10" }, - { "4.11" }, - { "4.12" } + return asList( new Object[][] { + { JUNIT_4_0 }, + { JUNIT_4_1 }, + { JUNIT_4_2 }, + { JUNIT_4_3 }, + { JUNIT_4_3_1 }, + { JUNIT_4_4 }, + { JUNIT_4_5 }, + { JUNIT_4_6 }, + { JUNIT_4_7 }, + { JUNIT_4_8 }, + { JUNIT_4_8_1 }, + { JUNIT_4_8_2 }, + { JUNIT_4_9 }, + { JUNIT_4_10 }, + { JUNIT_4_11 }, + { JUNIT_4_12 }, + { VINTAGE_5_1_1 }, + { JUPITER_5_1_1 } } ); } @Parameter - public String version; - - private SurefireLauncher unpack() - { - return unpack( "/junit4", version ); - } + public JUnitVersion version; @Test public void testJunit() - throws Exception { - runJUnitTest( version ); + version.configure( unpack() ) + .executeTest() + .verifyErrorFree( 1 ); } - public void runJUnitTest( String version ) - throws Exception + private SurefireLauncher unpack() { - unpack().setJUnitVersion( version ).executeTest().verifyErrorFree( 1 ); + return unpack( "/junit4", version.toString() ); } } diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit5IT.java similarity index 54% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit5IT.java index e9234f2..8c5eb3a 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnit5IT.java @@ -1,4 +1,4 @@ -package junit4; +package org.apache.maven.surefire.its; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,47 +19,27 @@ package junit4; * under the License. */ -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; import org.junit.Test; +import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaVersion; -public class BasicTest +/** + * Basic suite test currently only running against JUnit 5 M2 + * + * @author <a href="mailto:brit...@apache.org">Benedikt Ritter</a> + */ +public class JUnit5IT + extends SurefireJUnit4IntegrationTestCase { - private boolean setUpCalled = false; - - private static boolean tearDownCalled = false; - - @Before - public void setUp() - { - setUpCalled = true; - tearDownCalled = false; - System.out.println( "Called setUp" ); - } - - @After - public void tearDown() - { - setUpCalled = false; - tearDownCalled = true; - System.out.println( "Called tearDown" ); - } - @Test - public void testSetUp() + public void test() { - Assert.assertTrue( "setUp was not called", setUpCalled ); - } - + assumeJavaVersion( 1.8d ); - @AfterClass - public static void oneTimeTearDown() - { - + unpack( "/junit5" ) + .executeTest() + .verifyErrorFree( 2 ); } - } diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformIT.java similarity index 53% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformIT.java index e9234f2..f82206c 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformIT.java @@ -1,4 +1,4 @@ -package junit4; +package org.apache.maven.surefire.its; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,47 +19,29 @@ package junit4; * under the License. */ -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.apache.maven.surefire.its.fixture.SurefireLauncher; import org.junit.Test; +import static java.lang.System.getProperty; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assume.assumeThat; -public class BasicTest +public class JUnitPlatformIT + extends SurefireJUnit4IntegrationTestCase { - - private boolean setUpCalled = false; - - private static boolean tearDownCalled = false; - - @Before - public void setUp() - { - setUpCalled = true; - tearDownCalled = false; - System.out.println( "Called setUp" ); - } - - @After - public void tearDown() + private SurefireLauncher unpack() { - setUpCalled = false; - tearDownCalled = true; - System.out.println( "Called tearDown" ); + return unpack( "/junit-platform" ); } @Test - public void testSetUp() + public void test40() { - Assert.assertTrue( "setUp was not called", setUpCalled ); - } - + assumeThat( "java.specification.version: ", + getProperty( "java.specification.version" ), is( greaterThanOrEqualTo( "1.8" ) ) ); - @AfterClass - public static void oneTimeTearDown() - { - + unpack().executeTest().verifyErrorFree( 1 ); } - } diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitVersion.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitVersion.java new file mode 100644 index 0000000..8e7f606 --- /dev/null +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitVersion.java @@ -0,0 +1,80 @@ +package org.apache.maven.surefire.its; + +/* + * 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.apache.maven.surefire.its.fixture.SurefireLauncher; + +/** + * Enum listing all the JUnit version. + */ +public enum JUnitVersion { + + JUNIT_4_0( "4.0" ), + JUNIT_4_1( "4.1" ), + JUNIT_4_2( "4.2" ), + JUNIT_4_3( "4.3" ), + JUNIT_4_3_1( "4.3.1" ), + JUNIT_4_4( "4.4" ), + JUNIT_4_5( "4.5" ), + JUNIT_4_6( "4.6" ), + JUNIT_4_7( "4.7" ), + JUNIT_4_8( "4.8" ), + JUNIT_4_8_1( "4.8.1" ), + JUNIT_4_8_2( "4.8.2" ), + JUNIT_4_9( "4.9" ), + JUNIT_4_10( "4.10" ), + JUNIT_4_11( "4.11" ), + JUNIT_4_12( "4.12" ), + VINTAGE_5_1_1( "5.1.1" ) + { + @Override + public SurefireLauncher configure( SurefireLauncher launcher ) + { + return super.configure( launcher ) + .activateProfile( "junit5-vintage" ); + } + }, + JUPITER_5_1_1( "5.1.1" ) + { + @Override + public SurefireLauncher configure( SurefireLauncher launcher ) + { + return super.configure( launcher ) + .activateProfile( "junit5-jupiter" ); + } + }; + + private final String version; + + JUnitVersion( String version ) + { + this.version = version; + } + + public SurefireLauncher configure( SurefireLauncher launcher ) + { + return launcher.setJUnitVersion( version ); + } + + public String toString() + { + return version; + } +} diff --git a/surefire-its/src/test/resources/junit4/pom.xml b/surefire-its/src/test/resources/junit-platform/pom.xml similarity index 55% copy from surefire-its/src/test/resources/junit4/pom.xml copy to surefire-its/src/test/resources/junit-platform/pom.xml index 751a0e6..40a4f61 100644 --- a/surefire-its/src/test/resources/junit4/pom.xml +++ b/surefire-its/src/test/resources/junit-platform/pom.xml @@ -17,39 +17,38 @@ ~ specific language governing permissions and limitations ~ under the License. --> + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> + <modelVersion>4.0.0</modelVersion> - <groupId>org.apache.maven.plugins.surefire</groupId> - <artifactId>junit4</artifactId> - <version>1.0-SNAPSHOT</version> - <name>Test for JUnit 4</name> + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>junit-platform</artifactId> + <version>1.0</version> + <name>Test for JUnit 5 Platform</name> - <properties> - <junitVersion>4.4</junitVersion> - <maven.compiler.source>1.6</maven.compiler.source> - <maven.compiler.target>1.6</maven.compiler.target> - </properties> + <properties> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + </properties> - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>${junit.version}</version> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>${surefire.version}</version> - </plugin> - </plugins> - </build> + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>5.1.1</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + </plugin> + </plugins> + </build> </project> diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/resources/junit-platform/src/test/java/junitplatform/BasicTest.java similarity index 73% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/resources/junit-platform/src/test/java/junitplatform/BasicTest.java index e9234f2..2c9d119 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/resources/junit-platform/src/test/java/junitplatform/BasicTest.java @@ -1,4 +1,4 @@ -package junit4; +package junitplatform; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,21 +19,21 @@ package junit4; * under the License. */ -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class BasicTest { - private boolean setUpCalled = false; + private boolean setUpCalled; - private static boolean tearDownCalled = false; - - @Before + private static boolean tearDownCalled; + + @BeforeEach public void setUp() { setUpCalled = true; @@ -41,7 +41,7 @@ public class BasicTest System.out.println( "Called setUp" ); } - @After + @AfterEach public void tearDown() { setUpCalled = false; @@ -52,14 +52,14 @@ public class BasicTest @Test public void testSetUp() { - Assert.assertTrue( "setUp was not called", setUpCalled ); + assertTrue( setUpCalled, "setUp was not called" ); } - - @AfterClass + + @AfterAll public static void oneTimeTearDown() { - + assertTrue( tearDownCalled ); } } diff --git a/surefire-its/src/test/resources/junit4/pom.xml b/surefire-its/src/test/resources/junit4/pom.xml index 751a0e6..deddd56 100644 --- a/surefire-its/src/test/resources/junit4/pom.xml +++ b/surefire-its/src/test/resources/junit4/pom.xml @@ -20,36 +20,121 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> + <modelVersion>4.0.0</modelVersion> - <groupId>org.apache.maven.plugins.surefire</groupId> - <artifactId>junit4</artifactId> - <version>1.0-SNAPSHOT</version> - <name>Test for JUnit 4</name> + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>junit4</artifactId> + <version>1.0-SNAPSHOT</version> + <name>Test for JUnit 4</name> - <properties> - <junitVersion>4.4</junitVersion> - <maven.compiler.source>1.6</maven.compiler.source> - <maven.compiler.target>1.6</maven.compiler.target> - </properties> + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>5.1.1</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>${junit.version}</version> - <scope>test</scope> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>${surefire.version}</version> - </plugin> - </plugins> - </build> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>junit4</id> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <id>junit5-jupiter</id> + <properties> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <junit.jupiter.version>5.1.1</junit.jupiter.version> + <junit.vintage.version>5.1.1</junit.vintage.version> + <junit.platform.version>1.1.1</junit.platform.version> + </properties> + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <dependencies> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-surefire-provider</artifactId> + <version>${junit.platform.version}</version> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <version>${junit.jupiter.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <id>junit5-vintage</id> + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <junit.platform.version>1.1.1</junit.platform.version> + </properties> + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <dependencies> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-surefire-provider</artifactId> + <version>${junit.platform.version}</version> + </dependency> + <dependency> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + <version>${junit.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + </profile> + </profiles> </project> diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java index e9234f2..144df74 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java @@ -25,14 +25,12 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; - public class BasicTest { + private static boolean tearDownCalled = false; private boolean setUpCalled = false; - private static boolean tearDownCalled = false; - @Before public void setUp() { diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/resources/junit4/src/test/java/junit5/JUnit5Test.java similarity index 66% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/resources/junit4/src/test/java/junit5/JUnit5Test.java index e9234f2..0dd000c 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/resources/junit4/src/test/java/junit5/JUnit5Test.java @@ -1,4 +1,4 @@ -package junit4; +package junit5; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,32 +19,32 @@ package junit4; * under the License. */ -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class BasicTest +/** + * A test using the JUnit 5 API, which should be executed by JUnit jupiter enigne + */ +public class JUnit5Test { + private static boolean tearDownCalled; - private boolean setUpCalled = false; + private boolean setUpCalled; - private static boolean tearDownCalled = false; - - @Before + @BeforeEach public void setUp() { setUpCalled = true; - tearDownCalled = false; System.out.println( "Called setUp" ); } - @After + @AfterEach public void tearDown() { - setUpCalled = false; tearDownCalled = true; System.out.println( "Called tearDown" ); } @@ -52,14 +52,13 @@ public class BasicTest @Test public void testSetUp() { - Assert.assertTrue( "setUp was not called", setUpCalled ); + assertTrue( setUpCalled, "setUp was not called" ); } - - @AfterClass + @AfterAll public static void oneTimeTearDown() { - + assertTrue( tearDownCalled, "tearDown was not called" ); } } diff --git a/surefire-its/src/test/resources/junit5/pom.xml b/surefire-its/src/test/resources/junit5/pom.xml new file mode 100644 index 0000000..b44c2cc --- /dev/null +++ b/surefire-its/src/test/resources/junit5/pom.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>junit5</artifactId> + <version>1.0-SNAPSHOT</version> + <name>Test for JUnit 5</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <java.version>1.8</java.version> + <junit.jupiter.version>5.1.1</junit.jupiter.version> + <junit.vintage.version>5.1.1</junit.vintage.version> + <junit.platform.version>1.1.1</junit.platform.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <version>${junit.jupiter.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + <version>${junit.vintage.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>${java.version}</source> + <target>${java.version}</target> + </configuration> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <dependencies> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-surefire-provider</artifactId> + <version>${junit.platform.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + +</project> diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit4Test.java similarity index 83% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit4Test.java index e9234f2..0a94b1a 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit4Test.java @@ -1,4 +1,4 @@ -package junit4; +package junit5; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -25,26 +25,26 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; - -public class BasicTest +/** + * A test using the JUnit 4 API, which should be executed by JUnit vintage enigne + */ +public class JUnit4Test { - private boolean setUpCalled = false; + private boolean setUpCalled; + + private static boolean tearDownCalled; - private static boolean tearDownCalled = false; - @Before public void setUp() { setUpCalled = true; - tearDownCalled = false; System.out.println( "Called setUp" ); } @After public void tearDown() { - setUpCalled = false; tearDownCalled = true; System.out.println( "Called tearDown" ); } @@ -54,12 +54,11 @@ public class BasicTest { Assert.assertTrue( "setUp was not called", setUpCalled ); } - @AfterClass public static void oneTimeTearDown() { - + Assert.assertTrue( "tearDown was not called", tearDownCalled ); } } diff --git a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java b/surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit5Test.java similarity index 66% copy from surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java copy to surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit5Test.java index e9234f2..558546d 100644 --- a/surefire-its/src/test/resources/junit4/src/test/java/junit4/BasicTest.java +++ b/surefire-its/src/test/resources/junit5/src/test/java/junit5/JUnit5Test.java @@ -1,4 +1,4 @@ -package junit4; +package junit5; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,32 +19,33 @@ package junit4; * under the License. */ -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class BasicTest +/** + * A test using the JUnit 5 API, which should be executed by JUnit jupiter enigne + */ +public class JUnit5Test { - private boolean setUpCalled = false; + private boolean setUpCalled; + + private static boolean tearDownCalled; - private static boolean tearDownCalled = false; - - @Before + @BeforeEach public void setUp() { setUpCalled = true; - tearDownCalled = false; System.out.println( "Called setUp" ); } - @After + @AfterEach public void tearDown() { - setUpCalled = false; tearDownCalled = true; System.out.println( "Called tearDown" ); } @@ -52,14 +53,13 @@ public class BasicTest @Test public void testSetUp() { - Assert.assertTrue( "setUp was not called", setUpCalled ); + Assertions.assertTrue( setUpCalled, "setUp was not called" ); } - - @AfterClass + @AfterAll public static void oneTimeTearDown() { - + Assertions.assertTrue( tearDownCalled, "tearDown was not called" ); } } diff --git a/surefire-providers/pom.xml b/surefire-providers/pom.xml index 0322bcc..47b0f40 100644 --- a/surefire-providers/pom.xml +++ b/surefire-providers/pom.xml @@ -41,6 +41,7 @@ <module>surefire-junit3</module> <module>surefire-junit4</module> <module>surefire-junit47</module> + <module>surefire-junit-platform</module> <module>surefire-testng-utils</module> <module>surefire-testng</module> </modules> diff --git a/surefire-providers/surefire-junit-platform/pom.xml b/surefire-providers/surefire-junit-platform/pom.xml new file mode 100644 index 0000000..07fa180 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/pom.xml @@ -0,0 +1,167 @@ +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-providers</artifactId> + <version>3.0.0-SNAPSHOT</version> + </parent> + + <artifactId>surefire-junit-platform</artifactId> + <name>SureFire JUnit Platform Runner</name> + <description>SureFire JUnit Platform Runner</description> + <properties> + <javaVersion>8</javaVersion> + </properties> + <contributors> + <contributor> + <name>Konstantin Lutovich</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Shintaro Katafuchi</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Sam Brannen</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Stefan Bechtold</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Marc Philipp</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Matthias Merdes</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + <contributor> + <name>Johannes Link</name> + <roles> + <role>Contributed to the original provider implementation</role> + </roles> + </contributor> + </contributors> + + <dependencies> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>common-java5</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.junit.platform</groupId> + <artifactId>junit-platform-launcher</artifactId> + <version>1.1.1</version> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>5.1.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <version>5.1.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>3.6.0</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>animal-sniffer-maven-plugin</artifactId> + <executions> + <execution> + <id>signature-check</id> + <goals> + <goal>check</goal> + </goals> + <configuration> + <signature combine.self="override"> + <groupId>org.codehaus.mojo.signature</groupId> + <artifactId>java18</artifactId> + <version>1.0</version> + </signature> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <jvm>${java.home}/bin/java</jvm> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <artifactSet> + <includes> + <include>org.apache.maven.surefire:common-java5</include> + </includes> + </artifactSet> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java new file mode 100644 index 0000000..7f58921 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java @@ -0,0 +1,202 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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.apache.maven.surefire.providerapi.AbstractProvider; +import org.apache.maven.surefire.providerapi.ProviderParameters; +import org.apache.maven.surefire.report.ReporterException; +import org.apache.maven.surefire.report.ReporterFactory; +import org.apache.maven.surefire.report.RunListener; +import org.apache.maven.surefire.report.SimpleReportEntry; +import org.apache.maven.surefire.suite.RunResult; +import org.apache.maven.surefire.testset.TestSetFailedException; +import org.apache.maven.surefire.util.TestsToRun; +import org.junit.platform.engine.Filter; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TagFilter; +import org.junit.platform.launcher.core.LauncherFactory; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; + +/** + * @since 1.0 + */ +public class JUnitPlatformProvider + extends AbstractProvider +{ + + // Parameter names processed to determine which @Tags should be executed. + static final String EXCLUDE_GROUPS = "excludedGroups"; + + static final String EXCLUDE_TAGS = "excludeTags"; + + static final String INCLUDE_GROUPS = "groups"; + + static final String INCLUDE_TAGS = "includeTags"; + + static final String EXCEPTION_MESSAGE_BOTH_NOT_ALLOWED = "The " + INCLUDE_GROUPS + " and " + INCLUDE_TAGS + + " parameters (or the " + EXCLUDE_GROUPS + " and " + EXCLUDE_TAGS + " parameters) are synonyms - " + + "only one of each is allowed (though neither is required)."; + + private final ProviderParameters parameters; + + private final Launcher launcher; + + final Filter<?>[] includeAndExcludeFilters; + + public JUnitPlatformProvider( ProviderParameters parameters ) + { + this( parameters, LauncherFactory.create() ); + } + + JUnitPlatformProvider( ProviderParameters parameters, Launcher launcher ) + { + this.parameters = parameters; + this.launcher = launcher; + this.includeAndExcludeFilters = getIncludeAndExcludeFilters(); + Logger.getLogger( "org.junit" ).setLevel( Level.WARNING ); + } + + @Override + public Iterable<Class<?>> getSuites() + { + return scanClasspath(); + } + + @Override + public RunResult invoke( Object forkTestSet ) + throws TestSetFailedException, ReporterException, InvocationTargetException + { + if ( forkTestSet instanceof TestsToRun ) + { + return invokeAllTests( (TestsToRun) forkTestSet ); + } + else if ( forkTestSet instanceof Class ) + { + return invokeAllTests( TestsToRun.fromClass( (Class<?>) forkTestSet ) ); + } + else if ( forkTestSet == null ) + { + return invokeAllTests( scanClasspath() ); + } + else + { + throw new IllegalArgumentException( "Unexpected value of forkTestSet: " + forkTestSet ); + } + } + + private TestsToRun scanClasspath() + { + TestsToRun scannedClasses = parameters.getScanResult().applyFilter( + new TestPlanScannerFilter( launcher, includeAndExcludeFilters ), parameters.getTestClassLoader() ); + return parameters.getRunOrderCalculator().orderTestClasses( scannedClasses ); + } + + private RunResult invokeAllTests( TestsToRun testsToRun ) + { + RunResult runResult; + ReporterFactory reporterFactory = parameters.getReporterFactory(); + try + { + RunListener runListener = reporterFactory.createReporter(); + launcher.registerTestExecutionListeners( new RunListenerAdapter( runListener ) ); + + for ( Class<?> testClass : testsToRun ) + { + invokeSingleClass( testClass, runListener ); + } + } + finally + { + runResult = reporterFactory.close(); + } + return runResult; + } + + private void invokeSingleClass( Class<?> testClass, RunListener runListener ) + { + SimpleReportEntry classEntry = new SimpleReportEntry( getClass().getName(), testClass.getName() ); + runListener.testSetStarting( classEntry ); + + LauncherDiscoveryRequest discoveryRequest = request().selectors( selectClass( testClass ) ).filters( + includeAndExcludeFilters ).build(); + launcher.execute( discoveryRequest ); + + runListener.testSetCompleted( classEntry ); + } + + private Filter<?>[] getIncludeAndExcludeFilters() + { + List<Filter<?>> filters = new ArrayList<>(); + + Optional<List<String>> includes = getGroupsOrTags( getPropertiesList( INCLUDE_GROUPS ), + getPropertiesList( INCLUDE_TAGS ) ); + includes.map( TagFilter::includeTags ).ifPresent( filters::add ); + + Optional<List<String>> excludes = getGroupsOrTags( getPropertiesList( EXCLUDE_GROUPS ), + getPropertiesList( EXCLUDE_TAGS ) ); + excludes.map( TagFilter::excludeTags ).ifPresent( filters::add ); + + return filters.toArray( new Filter<?>[filters.size()] ); + } + + private Optional<List<String>> getPropertiesList( String key ) + { + List<String> compoundProperties = null; + String property = parameters.getProviderProperties().get( key ); + if ( property != null ) + { + compoundProperties = Arrays.asList( property.split( "[, ]+" ) ); + } + return Optional.ofNullable( compoundProperties ); + } + + private Optional<List<String>> getGroupsOrTags( Optional<List<String>> groups, Optional<List<String>> tags ) + { + Optional<List<String>> elements = Optional.empty(); + + if ( groups.isPresent() && tags.isPresent() ) + { + throw new IllegalStateException( EXCEPTION_MESSAGE_BOTH_NOT_ALLOWED ); + } + + if ( groups.isPresent() ) + { + elements = groups; + } + else if ( tags.isPresent() ) + { + elements = tags; + } + + return elements; + } + +} 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 new file mode 100644 index 0000000..9191864 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java @@ -0,0 +1,150 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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 org.apache.maven.surefire.report.SimpleReportEntry.ignored; +import static org.junit.platform.engine.TestExecutionResult.Status.ABORTED; +import static org.junit.platform.engine.TestExecutionResult.Status.FAILED; + +import java.util.Optional; + +import org.apache.maven.surefire.report.PojoStackTraceWriter; +import org.apache.maven.surefire.report.RunListener; +import org.apache.maven.surefire.report.SimpleReportEntry; +import org.apache.maven.surefire.report.StackTraceWriter; +import org.junit.platform.engine.TestExecutionResult; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.engine.support.descriptor.MethodSource; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +/** + * @since 1.0 + */ +final class RunListenerAdapter + implements TestExecutionListener +{ + + private final RunListener runListener; + + private Optional<TestPlan> testPlan = Optional.empty(); + + public RunListenerAdapter( RunListener runListener ) + { + this.runListener = runListener; + } + + @Override + public void testPlanExecutionStarted( TestPlan testPlan ) + { + this.testPlan = Optional.of( testPlan ); + } + + @Override + public void testPlanExecutionFinished( TestPlan testPlan ) + { + this.testPlan = Optional.empty(); + } + + @Override + public void executionStarted( TestIdentifier testIdentifier ) + { + if ( testIdentifier.isTest() ) + { + runListener.testStarting( createReportEntry( testIdentifier, Optional.empty() ) ); + } + } + + @Override + public void executionSkipped( TestIdentifier testIdentifier, String reason ) + { + String source = getClassName( testIdentifier ).orElseGet( () -> parentDisplayName( testIdentifier ) ); + runListener.testSkipped( ignored( source, testIdentifier.getDisplayName(), reason ) ); + } + + @Override + public void executionFinished( TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) + { + if ( testExecutionResult.getStatus() == ABORTED ) + { + runListener.testAssumptionFailure( createReportEntry( testIdentifier, + testExecutionResult.getThrowable() ) ); + } + else if ( testExecutionResult.getStatus() == FAILED ) + { + runListener.testFailed( createReportEntry( testIdentifier, testExecutionResult.getThrowable() ) ); + } + else if ( testIdentifier.isTest() ) + { + runListener.testSucceeded( createReportEntry( testIdentifier, Optional.empty() ) ); + } + } + + private SimpleReportEntry createReportEntry( TestIdentifier testIdentifier, Optional<Throwable> throwable ) + { + Optional<String> className = getClassName( testIdentifier ); + if ( className.isPresent() ) + { + StackTraceWriter traceWriter = new PojoStackTraceWriter( className.get(), + getMethodName( testIdentifier ).orElse( "" ), throwable.orElse( null ) ); + return new SimpleReportEntry( className.get(), testIdentifier.getDisplayName(), traceWriter, + (Integer) null ); + } + else + { + return new SimpleReportEntry( parentDisplayName( testIdentifier ), testIdentifier.getDisplayName(), + (Integer) null ); + } + } + + private Optional<String> getClassName( TestIdentifier testIdentifier ) + { + TestSource testSource = testIdentifier.getSource().orElse( null ); + if ( testSource instanceof ClassSource ) + { + return Optional.of( ( (ClassSource) testSource ).getJavaClass().getName() ); + } + if ( testSource instanceof MethodSource ) + { + return Optional.of( ( (MethodSource) testSource ).getClassName() ); + } + return Optional.empty(); + } + + private Optional<String> getMethodName( TestIdentifier testIdentifier ) + { + TestSource testSource = testIdentifier.getSource().orElse( null ); + if ( testSource instanceof MethodSource ) + { + return Optional.of( ( (MethodSource) testSource ).getMethodName() ); + } + return Optional.empty(); + } + + private String parentDisplayName( TestIdentifier testIdentifier ) + { + return testPlan + .flatMap( plan -> plan.getParent( testIdentifier ) ) + .map( TestIdentifier::getDisplayName ) + .orElseGet( testIdentifier::getUniqueId ); + } +} diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilter.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilter.java new file mode 100644 index 0000000..4a95d6e --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilter.java @@ -0,0 +1,64 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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 org.junit.platform.engine.discovery.DiscoverySelectors.selectClass; +import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request; + +import java.util.function.Predicate; + +import org.apache.maven.surefire.util.ScannerFilter; +import org.junit.platform.engine.Filter; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +/** + * @since 1.0 + */ +final class TestPlanScannerFilter + implements ScannerFilter +{ + + private static final Predicate<TestIdentifier> HAS_TESTS = testIdentifier -> testIdentifier.isTest() + || testIdentifier.isContainer(); + + private final Launcher launcher; + + private final Filter<?>[] includeAndExcludeFilters; + + public TestPlanScannerFilter( Launcher launcher, Filter<?>[] includeAndExcludeFilters ) + { + this.launcher = launcher; + this.includeAndExcludeFilters = includeAndExcludeFilters; + } + + @Override + @SuppressWarnings( "rawtypes" ) + public boolean accept( Class testClass ) + { + LauncherDiscoveryRequest discoveryRequest = request().selectors( selectClass( testClass ) ).filters( + includeAndExcludeFilters ).build(); + TestPlan testPlan = launcher.discover( discoveryRequest ); + return testPlan.countTestIdentifiers( HAS_TESTS ) > 0; + } + +} diff --git a/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.providerapi.SurefireProvider b/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.providerapi.SurefireProvider new file mode 100644 index 0000000..dbe73cf --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/main/resources/META-INF/services/org.apache.maven.surefire.providerapi.SurefireProvider @@ -0,0 +1 @@ +org.apache.maven.surefire.junitplatform.JUnitPlatformProvider diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTests.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTests.java new file mode 100644 index 0000000..a32aade --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTests.java @@ -0,0 +1,325 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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 org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; + +import org.apache.maven.surefire.providerapi.ProviderParameters; +import org.apache.maven.surefire.report.ReporterFactory; +import org.apache.maven.surefire.report.RunListener; +import org.apache.maven.surefire.util.RunOrderCalculator; +import org.apache.maven.surefire.util.ScanResult; +import org.apache.maven.surefire.util.TestsToRun; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.platform.commons.util.PreconditionViolationException; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +/** + * Unit tests for {@link JUnitPlatformProvider}. + * + * @since 1.0 + */ +class JUnitPlatformProviderTests +{ + + @Test + void getSuitesReturnsScannedClasses() + throws Exception + { + ProviderParameters providerParameters = providerParametersMock( TestClass1.class, TestClass2.class ); + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertThat( provider.getSuites() ).containsOnly( TestClass1.class, TestClass2.class ); + } + + @Test + void invokeThrowsForWrongForkTestSet() + throws Exception + { + ProviderParameters providerParameters = providerParametersMock( Integer.class ); + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertThrows( IllegalArgumentException.class, () -> provider.invoke( "wrong forkTestSet" ) ); + } + + @Test + void allGivenTestsToRunAreInvoked() + throws Exception + { + Launcher launcher = LauncherFactory.create(); + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher ); + + TestPlanSummaryListener executionListener = new TestPlanSummaryListener(); + launcher.registerTestExecutionListeners( executionListener ); + + TestsToRun testsToRun = newTestsToRun( TestClass1.class, TestClass2.class ); + provider.invoke( testsToRun ); + + assertThat( executionListener.summaries ).hasSize( 2 ); + TestClass1.verifyExecutionSummary( executionListener.summaries.get( 0 ) ); + TestClass2.verifyExecutionSummary( executionListener.summaries.get( 1 ) ); + } + + @Test + void singleTestClassIsInvoked() + throws Exception + { + Launcher launcher = LauncherFactory.create(); + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParametersMock(), launcher ); + + TestPlanSummaryListener executionListener = new TestPlanSummaryListener(); + launcher.registerTestExecutionListeners( executionListener ); + + provider.invoke( TestClass1.class ); + + assertThat( executionListener.summaries ).hasSize( 1 ); + TestClass1.verifyExecutionSummary( executionListener.summaries.get( 0 ) ); + } + + @Test + void allDiscoveredTestsAreInvokedForNullArgument() + throws Exception + { + ProviderParameters providerParameters = providerParametersMock( TestClass1.class, TestClass2.class ); + Launcher launcher = LauncherFactory.create(); + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters, launcher ); + + TestPlanSummaryListener executionListener = new TestPlanSummaryListener(); + launcher.registerTestExecutionListeners( executionListener ); + + provider.invoke( null ); + + assertThat( executionListener.summaries ).hasSize( 2 ); + TestClass1.verifyExecutionSummary( executionListener.summaries.get( 0 ) ); + TestClass2.verifyExecutionSummary( executionListener.summaries.get( 1 ) ); + } + + @Test + void bothGroupsAndIncludeTagsThrowsException() + { + Map<String, String> properties = new HashMap<>(); + properties.put( JUnitPlatformProvider.INCLUDE_GROUPS, "groupOne, groupTwo" ); + properties.put( JUnitPlatformProvider.INCLUDE_TAGS, "tagOne, tagTwo" ); + verifyPreconditionViolationException( properties ); + } + + @Test + void bothExcludedGroupsAndExcludeTagsThrowsException() { + Map<String, String> properties = new HashMap<>(); + properties.put(JUnitPlatformProvider.EXCLUDE_GROUPS, "groupOne, groupTwo"); + properties.put(JUnitPlatformProvider.EXCLUDE_TAGS, "tagOne, tagTwo"); + verifyPreconditionViolationException(properties); + } + + @Test + void onlyGroupsIsDeclared() + throws Exception + { + Map<String, String> properties = new HashMap<>(); + properties.put( JUnitPlatformProvider.INCLUDE_GROUPS, "groupOne, groupTwo" ); + + ProviderParameters providerParameters = providerParametersMock( TestClass1.class ); + when( providerParameters.getProviderProperties() ).thenReturn( properties ); + + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertEquals( 1, provider.includeAndExcludeFilters.length ); + } + + @Test + void onlyExcludeTagsIsDeclared() + throws Exception + { + Map<String, String> properties = new HashMap<>(); + properties.put( JUnitPlatformProvider.EXCLUDE_TAGS, "tagOne, tagTwo" ); + + ProviderParameters providerParameters = providerParametersMock( TestClass1.class ); + when( providerParameters.getProviderProperties() ).thenReturn( properties ); + + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertEquals( 1, provider.includeAndExcludeFilters.length ); + } + + @Test + void bothIncludeAndExcludeAreAllowed() + throws Exception + { + Map<String, String> properties = new HashMap<>(); + properties.put( JUnitPlatformProvider.INCLUDE_TAGS, "tagOne, tagTwo" ); + properties.put( JUnitPlatformProvider.EXCLUDE_TAGS, "tagThree, tagFour" ); + + ProviderParameters providerParameters = providerParametersMock( TestClass1.class ); + when( providerParameters.getProviderProperties() ).thenReturn( properties ); + + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertEquals( 2, provider.includeAndExcludeFilters.length ); + } + + @Test + void noFiltersAreCreatedIfNoPropertiesAreDeclared() + throws Exception + { + ProviderParameters providerParameters = providerParametersMock( TestClass1.class ); + + JUnitPlatformProvider provider = new JUnitPlatformProvider( providerParameters ); + + assertEquals( 0, provider.includeAndExcludeFilters.length ); + } + + private void verifyPreconditionViolationException( Map<String, String> properties ) + { + ProviderParameters providerParameters = providerParametersMock( TestClass1.class ); + when( providerParameters.getProviderProperties() ).thenReturn( properties ); + + Throwable throwable = assertThrows( PreconditionViolationException.class, () -> + new JUnitPlatformProvider(providerParameters) ); + + assertEquals( JUnitPlatformProvider.EXCEPTION_MESSAGE_BOTH_NOT_ALLOWED, throwable.getMessage() ); + } + + private static ProviderParameters providerParametersMock( Class<?>... testClasses ) + { + TestsToRun testsToRun = newTestsToRun( testClasses ); + + ScanResult scanResult = mock( ScanResult.class ); + when( scanResult.applyFilter( any(), any() ) ).thenReturn( testsToRun ); + + RunOrderCalculator runOrderCalculator = mock( RunOrderCalculator.class ); + when( runOrderCalculator.orderTestClasses( any() ) ).thenReturn( testsToRun ); + + ReporterFactory reporterFactory = mock( ReporterFactory.class ); + RunListener runListener = mock( RunListener.class ); + when( reporterFactory.createReporter() ).thenReturn( runListener ); + + ProviderParameters providerParameters = mock( ProviderParameters.class ); + when( providerParameters.getScanResult() ).thenReturn( scanResult ); + when( providerParameters.getRunOrderCalculator() ).thenReturn( runOrderCalculator ); + when( providerParameters.getReporterFactory() ).thenReturn( reporterFactory ); + + return providerParameters; + } + + private static TestsToRun newTestsToRun( Class<?>... testClasses ) + { + List<Class<?>> classesList = Arrays.asList( testClasses ); + return new TestsToRun( new LinkedHashSet<>( classesList ) ); + } + + private class TestPlanSummaryListener + extends SummaryGeneratingListener + { + + final List<TestExecutionSummary> summaries = new ArrayList<>(); + + @Override + public void testPlanExecutionFinished( TestPlan testPlan ) + { + super.testPlanExecutionFinished( testPlan ); + summaries.add( getSummary() ); + } + } + + private static class TestClass1 + { + + @Test + void test1() + { + } + + @Test + void test2() + { + } + + @Disabled + @Test + void test3() + { + } + + @Test + void test4() + { + throw new RuntimeException(); + } + + static void verifyExecutionSummary( TestExecutionSummary summary ) + { + assertEquals( 4, summary.getTestsFoundCount() ); + assertEquals( 3, summary.getTestsStartedCount() ); + assertEquals( 2, summary.getTestsSucceededCount() ); + assertEquals( 1, summary.getTestsSkippedCount() ); + assertEquals( 0, summary.getTestsAbortedCount() ); + assertEquals( 1, summary.getTestsFailedCount() ); + } + } + + private static class TestClass2 + { + + @Test + void test1() + { + } + + @Test + void test2() + { + throw new RuntimeException(); + } + + @Test + void test3() + { + assumeTrue( false ); + } + + static void verifyExecutionSummary( TestExecutionSummary summary ) + { + assertEquals( 3, summary.getTestsFoundCount() ); + assertEquals( 3, summary.getTestsStartedCount() ); + assertEquals( 1, summary.getTestsSucceededCount() ); + assertEquals( 0, summary.getTestsSkippedCount() ); + assertEquals( 1, summary.getTestsAbortedCount() ); + assertEquals( 1, summary.getTestsFailedCount() ); + } + } +} diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTests.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTests.java new file mode 100644 index 0000000..0a37eb5 --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTests.java @@ -0,0 +1,252 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Optional; + +import org.apache.maven.surefire.report.ReportEntry; +import org.apache.maven.surefire.report.RunListener; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.engine.descriptor.ClassTestDescriptor; +import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor; +import org.junit.platform.engine.TestDescriptor; +import org.junit.platform.engine.TestExecutionResult; +import org.junit.platform.engine.UniqueId; +import org.junit.platform.engine.support.descriptor.EngineDescriptor; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; +import org.mockito.ArgumentCaptor; + +/** + * Unit tests for {@link RunListenerAdapter}. + * + * @since 1.0 + */ +class RunListenerAdapterTests +{ + private RunListener listener; + private RunListenerAdapter adapter; + + @BeforeEach + void setUp() + { + listener = mock( RunListener.class ); + adapter = new RunListenerAdapter( listener ); + } + + @Test + void notifiedWithCorrectNamesWhenMethodExecutionStarted() + throws Exception + { + ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + + adapter.executionStarted( newMethodIdentifier() ); + verify( listener ).testStarting( entryCaptor.capture() ); + + ReportEntry entry = entryCaptor.getValue(); + assertEquals( MY_TEST_METHOD_NAME + "()", entry.getName() ); + assertEquals( MyTestClass.class.getName(), entry.getSourceName() ); + assertNotNull( entry.getStackTraceWriter() ); + } + + @Test + void notNotifiedWhenClassExecutionStarted() + { + adapter.executionStarted( newClassIdentifier() ); + verify( listener, never() ).testStarting( any() ); + } + + @Test + void notNotifiedWhenEngineExecutionStarted() + { + adapter.executionStarted( newEngineIdentifier() ); + verify( listener, never() ).testStarting( any() ); + } + + @Test + void notifiedWhenMethodExecutionSkipped() + throws Exception + { + adapter.executionSkipped( newMethodIdentifier(), "test" ); + verify( listener ).testSkipped( any() ); + } + + @Test + void notifiedWithCorrectNamesWhenClassExecutionSkipped() + { + ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + + adapter.executionSkipped( newClassIdentifier(), "test" ); + verify( listener ).testSkipped( entryCaptor.capture() ); + + ReportEntry entry = entryCaptor.getValue(); + assertTrue( MyTestClass.class.getTypeName().contains( entry.getName() ) ); + assertEquals( MyTestClass.class.getName(), entry.getSourceName() ); + } + + @Test + void notifiedWhenEngineExecutionSkipped() + { + adapter.executionSkipped( newEngineIdentifier(), "test" ); + verify( listener ).testSkipped( any() ); + } + + @Test + void notifiedWhenMethodExecutionAborted() + throws Exception + { + adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.aborted( null ) ); + verify( listener ).testAssumptionFailure( any() ); + } + + @Test + void notifiedWhenClassExecutionAborted() + { + adapter.executionFinished( newClassIdentifier(), TestExecutionResult.aborted( null ) ); + verify( listener ).testAssumptionFailure( any() ); + } + + @Test + void notifiedWhenMethodExecutionFailed() + throws Exception + { + adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.failed( new RuntimeException() ) ); + verify( listener ).testFailed( any() ); + } + + @Test + void notifiedWithCorrectNamesWhenClassExecutionFailed() + { + ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + + adapter.executionFinished( newClassIdentifier(), TestExecutionResult.failed( new RuntimeException() ) ); + verify( listener ).testFailed( entryCaptor.capture() ); + + ReportEntry entry = entryCaptor.getValue(); + assertEquals( MyTestClass.class.getName(), entry.getSourceName() ); + assertNotNull( entry.getStackTraceWriter() ); + } + + @Test + void notifiedWhenMethodExecutionSucceeded() + throws Exception + { + adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.successful() ); + verify( listener ).testSucceeded( any() ); + } + + @Test + void notNotifiedWhenClassExecutionSucceeded() + { + adapter.executionFinished( newClassIdentifier(), TestExecutionResult.successful() ); + verify( listener, never() ).testSucceeded( any() ); + } + + @Test + void notifiedWithParentDisplayNameWhenTestClassUnknown() + { + // Set up a test plan + TestPlan plan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) ); + adapter.testPlanExecutionStarted( plan ); + + // Use the test plan to set up child with parent. + final String parentDisplay = "I am your father"; + TestIdentifier child = newSourcelessIdentifierWithParent( plan, parentDisplay ); + adapter.executionStarted( child ); + + // Check that the adapter has informed Surefire that the test has been invoked, + // with the parent name as source (since the test case itself had no source). + ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + verify( listener ).testStarting( entryCaptor.capture() ); + assertEquals( parentDisplay, entryCaptor.getValue().getSourceName() ); + } + + private static TestIdentifier newMethodIdentifier() + throws Exception + { + TestDescriptor testDescriptor = new TestMethodTestDescriptor( newId(), MyTestClass.class, + MyTestClass.class.getDeclaredMethod( MY_TEST_METHOD_NAME ) ); + return TestIdentifier.from( testDescriptor ); + } + + private static TestIdentifier newClassIdentifier() + { + TestDescriptor testDescriptor = new ClassTestDescriptor( newId(), MyTestClass.class ); + return TestIdentifier.from( testDescriptor ); + } + + private static TestIdentifier newSourcelessIdentifierWithParent( TestPlan testPlan, String parentDisplay ) + { + // A parent test identifier with a name. + TestDescriptor parent = mock( TestDescriptor.class ); + when( parent.getUniqueId() ).thenReturn( newId() ); + when( parent.getDisplayName() ).thenReturn( parentDisplay ); + TestIdentifier parentId = TestIdentifier.from( parent ); + + // The (child) test case that is to be executed as part of a test plan. + TestDescriptor child = mock( TestDescriptor.class ); + when( child.getUniqueId() ).thenReturn( newId() ); + when( child.isTest() ).thenReturn( true ); + + // Ensure the child source is null yet that there is a parent -- the special case to be tested. + when( child.getSource() ).thenReturn( Optional.empty() ); + when( child.getParent() ).thenReturn( Optional.of(parent) ); + TestIdentifier childId = TestIdentifier.from( child ); + + testPlan.add( childId ); + testPlan.add( parentId ); + + return childId; + } + + private static TestIdentifier newEngineIdentifier() + { + TestDescriptor testDescriptor = new EngineDescriptor( newId(), "engine" ); + return TestIdentifier.from( testDescriptor ); + } + + private static UniqueId newId() + { + return UniqueId.forEngine( "engine" ); + } + + private static final String MY_TEST_METHOD_NAME = "myTestMethod"; + + private static class MyTestClass { + + @Test + void myTestMethod() + { + } + + } + +} diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilterTests.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilterTests.java new file mode 100644 index 0000000..98f5b2b --- /dev/null +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/TestPlanScannerFilterTests.java @@ -0,0 +1,190 @@ +package org.apache.maven.surefire.junitplatform; + +/* + * 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.util.Collections.emptyList; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestFactory; +import org.junit.platform.engine.Filter; +import org.junit.platform.launcher.core.LauncherFactory; + +/** + * Unit tests for {@link TestPlanScannerFilter}. + * + * @since 1.0 + */ +public class TestPlanScannerFilterTests +{ + + @Test + void emptyClassAccepted() + { + assertTrue( newFilter().accept( EmptyClass.class ), "accepts empty class because it is a container" ); + } + + @Test + void classWithNoTestMethodsIsAccepted() + { + assertTrue( newFilter().accept( ClassWithMethods.class ), + "accepts class with no @Test methods because it is a container" ); + } + + @Test + void classWithTestMethodsIsAccepted() + { + assertTrue( newFilter().accept( ClassWithTestMethods.class ) ); + } + + @Test + void classWithNestedTestClassIsAccepted() + { + assertTrue( newFilter().accept( ClassWithNestedTestClass.class ) ); + } + + @Test + void classWithDeeplyNestedTestClassIsAccepted() + { + assertTrue( newFilter().accept( ClassWithDeeplyNestedTestClass.class ) ); + } + + @Test + void classWithTestFactoryIsAccepted() + { + assertTrue( newFilter().accept( ClassWithTestFactory.class ) ); + } + + @Test + void classWithNestedTestFactoryIsAccepted() + { + assertTrue( newFilter().accept( ClassWithNestedTestFactory.class ) ); + } + + private TestPlanScannerFilter newFilter() + { + return new TestPlanScannerFilter( LauncherFactory.create(), new Filter<?>[0] ); + } + + private static class EmptyClass + { + } + + @SuppressWarnings("unused") + private static class ClassWithMethods + { + + void method1() + { + } + + void method2() + { + } + } + + private static class ClassWithTestMethods + { + + @Test + void test1() + { + } + + @Test + public void test2() + { + } + } + + private static class ClassWithNestedTestClass + { + + @SuppressWarnings("unused") + void method() + { + } + + @Nested + class TestClass + { + + @Test + void test1() + { + } + } + } + + private static class ClassWithDeeplyNestedTestClass + { + + @Nested + class Level1 + { + + @Nested + class Level2 + { + + @Nested + class TestClass + { + + @Test + void test1() + { + } + } + } + } + } + + private static class ClassWithTestFactory + { + + @TestFactory + Stream<DynamicTest> tests() + { + return Stream.empty(); + } + } + + private static class ClassWithNestedTestFactory + { + + @Nested + class TestClass + { + + @TestFactory + List<DynamicTest> tests() + { + return emptyList(); + } + } + } + +} -- To stop receiving notification emails like this one, please contact tibordig...@apache.org.