Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Donate current sources from junit-platform-surefire-provider #184

Merged
merged 1 commit into from
Jun 7, 2018
Merged
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 @@ -487,6 +487,15 @@ public abstract class AbstractSurefireMojo
@Parameter( property = "junitArtifactName", defaultValue = "junit:junit" )
private String junitArtifactName;

/**
* Allows you to specify the name of the JUnit Platform artifact.
* If not set, {@code org.junit.platform:junit-platform-engine} will be used.
*
* @since 2.22.0
*/
@Parameter( property = "junitPlatformArtifactName", defaultValue = "org.junit.platform:junit-platform-engine" )
private String junitPlatformArtifactName;

/**
* Allows you to specify the name of the TestNG artifact. If not set, {@code org.testng:testng} will be used.
*
Expand Down Expand Up @@ -1057,6 +1066,7 @@ protected List<ProviderInfo> createProviders()
Artifact junitDepArtifact = getJunitDepArtifact();
return new ProviderList( new DynamicProviderInfo( null ),
new TestNgProviderInfo( getTestNgArtifact() ),
new JUnitPlatformProviderInfo( getJunitPlatformArtifact() ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the order of provider-info was changed. Does it mean something important for functionality?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the built-in providers documented somewhere? I couldn't find any external information.

The first auto-detected provider wins, right?

If I understand the isApplicable() logic correctly, the platform info needs to checked before the legacy JUnit (3 + 4) infos. This is due to fact, that a legacy "junit-4.12.jar" is present in both cases: the users is on 4 and wants to run JUnit 4 test cases. Or the user is on "5" and wants to Vintage Engine to execute JUnit 4 or 3 test cases.

So, when we find org.junit.platform:junit-platform-engine as a dependency the uses wants to launch the JUnit Platform -- perhaps with the Vintage Engine which brings along JUnit 4.x jar.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK the found providers are run separately in a loop, see AbstractSurefireMojo.java in method execute.

new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit3ProviderInfo() )
Expand Down Expand Up @@ -1575,7 +1585,7 @@ private boolean isAnyJunit4( Artifact artifact )
return dependencyResolver.isWithinVersionSpec( artifact, "[4.0,)" );
}

static boolean isForkModeNever( String forkMode )
private static boolean isForkModeNever( String forkMode )
{
return FORK_NEVER.equals( forkMode );
}
Expand Down Expand Up @@ -2068,6 +2078,21 @@ private Artifact getJunitDepArtifact()
return getProjectArtifactMap().get( "junit:junit-dep" );
}


private Artifact getJunitPlatformArtifact()
{
Artifact artifact = getProjectArtifactMap().get( getJunitPlatformArtifactName() );
Artifact projectArtifact = project.getArtifact();
String projectArtifactName = projectArtifact.getGroupId() + ":" + projectArtifact.getArtifactId();

if ( artifact == null && projectArtifactName.equals( getJunitPlatformArtifactName() ) )
{
artifact = projectArtifact;
}

return artifact;
}

private ForkStarter createForkStarter( @Nonnull ProviderInfo provider, @Nonnull ForkConfiguration forkConfiguration,
@Nonnull ClassLoaderConfiguration classLoaderConfiguration,
@Nonnull RunOrderParameters runOrderParameters, @Nonnull ConsoleLogger log,
Expand Down Expand Up @@ -2695,7 +2720,8 @@ private void warnIfDefunctGroupsCombinations()
{
Artifact junitArtifact = getJunitArtifact();
boolean junit47Compatible = isJunit47Compatible( junitArtifact );
if ( !junit47Compatible )
boolean junit5PlatformCompatible = getJunitPlatformArtifact() != null;
if ( !junit47Compatible && !junit5PlatformCompatible )
{
if ( junitArtifact != null )
{
Expand All @@ -2704,8 +2730,8 @@ private void warnIfDefunctGroupsCombinations()
+ "Check your dependency:tree to see if your project "
+ "is picking up an old junit version" );
}
throw new MojoFailureException( "groups/excludedGroups require TestNG or JUnit48+ on project test "
+ "classpath" );
throw new MojoFailureException( "groups/excludedGroups require TestNG, JUnit48+ or JUnit 5 "
+ "on project test classpath" );
}
}

Expand Down Expand Up @@ -2908,6 +2934,40 @@ public Classpath getProviderClasspath()

}

final class JUnitPlatformProviderInfo
implements ProviderInfo
{
private final Artifact junitArtifact;

JUnitPlatformProviderInfo( Artifact junitArtifact )
{
this.junitArtifact = junitArtifact;
}

@Nonnull public String getProviderName()
{
return "org.apache.maven.surefire.junitplatform.JUnitPlatformProvider";
}

public boolean isApplicable()
{
return junitArtifact != null;
}

public void addProviderProperties() throws MojoExecutionException
{
convertGroupParameters();
}

public Classpath getProviderClasspath()
throws ArtifactResolutionException, ArtifactNotFoundException
{
return dependencyResolver.getProviderClasspath( "surefire-junit-platform",
surefireBooterArtifact.getBaseVersion(),
null );
}
}

final class JUnitCoreProviderInfo
implements ProviderInfo
{
Expand Down Expand Up @@ -3364,6 +3424,17 @@ public void setJunitArtifactName( String junitArtifactName )
this.junitArtifactName = junitArtifactName;
}

public String getJunitPlatformArtifactName()
{
return junitPlatformArtifactName;
}

@SuppressWarnings( "UnusedDeclaration" )
public void setJunitPlatformArtifactName( String junitPlatformArtifactName )
{
this.junitPlatformArtifactName = junitPlatformArtifactName;
}

public String getTestNGArtifactName()
{
return testNGArtifactName;
Expand Down
200 changes: 200 additions & 0 deletions maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
------
Using JUnit 5 Platform
------
JUnit Lambda Team <junit-lambda-team@googlegroups.com>
------
2018-05-14
------

~~ 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.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html

Using JUnit 5 Platform

* Configuring JUnit Platform

To get started with JUnit Platform, you need to add at least a single <<<TestEngine>>> implementation
to your project. For example, if you want to write tests with Jupiter, add the test artifact
<<<junit-jupiter-engine>>> to the dependencies in POM:

+---+
<dependencies>
[...]
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
+---+

This will pull in all required dependencies. Among those dependencies is <<<junit-jupiter-api>>> which contains
the classes and interfaces your test source requires to compile. <<<junit-platform-engine>>> is also resolved and
added.

This is the only step that is required to get started - you can now create tests in your test source directory
(e.g., <<<src/test/java>>>).

If you want to write and execute JUnit 3 or 4 tests via the JUnit Platform add the Vintage Engine to the
dependencies:

+---+
<dependencies>
[...]
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
+---+

* Provider Selection

If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:

+---+
if the JUnit 5 Platform Engine is present in the project
use junit-platform
if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value
use junit47 provider
if JUnit >= 4.0 is present
use junit4 provider
else
use junit3.8.1
+---+

When using this technique there is no check that the proper test-frameworks are present on your project's
classpath. Failing to add the proper test-frameworks will result in a build failure.

* Running Tests in Parallel

From JUnit Platform does not support running tests in parallel.

* Running a Single Test Class

The JUnit Platform Provider supports the <<<test>>> JVM system property supported by
the Maven Surefire Plugin. For example, to run only test methods in the <<<org.example.MyTest>>> test class
you can execute <<<mvn -Dtest=org.example.MyTest test>>> from the command line.


* Filtering by Test Class Names

The Maven Surefire Plugin will scan for test classes whose fully qualified names match
the following patterns.

* <<<**/Test*.java>>>

* <<<**/*Test.java>>>

* <<<**/*Tests.java>>>

* <<<**/*TestCase.java>>>

Moreover, it will exclude all nested classes (including static member classes) by default.

Note, however, that you can override this default behavior by configuring explicit
`include` and `exclude` rules in your `pom.xml` file. For example, to keep Maven Surefire
from excluding static member classes, you can override its exclude rules.

* Overriding exclude rules of Maven Surefire

+---+
...
<build>
<plugins>
...
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<excludes>
<exclude>some test to exclude here</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
...
+---+


* Filtering by Tags

You can use JUnit5 Tags and filter tests by tags or tag expressions.

* to include <<<tags>>> or <<<tag expressions>>>, use <<<groups>>>.

* to exclude <<<tags>>> or <<<tag expressions>>>, use either <<<excludedGroups>>>.

+---+
...
<build>
<plugins>
...
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<groups>acceptance | !feature-a</groups>
<excludedGroups>integration, regression</excludedGroups>
</configuration>
</plugin>
</plugins>
</build>
...
+---+


* Configuration Parameters

You can set JUnit Platform configuration parameters to influence test discovery and execution by
declaring the <<<configurationParameters>>> property and providing key-value pairs using the Java
<<<Properties>>> file syntax (as shown below) or via the <<<junit-platform.properties>>> file.

+---+
...
<build>
<plugins>
...
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<properties>
<configurationParameters>
junit.jupiter.conditions.deactivate = *
junit.jupiter.extensions.autodetection.enabled = true
junit.jupiter.testinstance.lifecycle.default = per_class
</configurationParameters>
</properties>
</configuration>
</plugin>
</plugins>
</build>
...
+---+
15 changes: 9 additions & 6 deletions maven-surefire-plugin/src/site/apt/examples/junit.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ Using JUnit
If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:

+---+
if the JUnit version in the project >= 4.7 and the parallel attribute has ANY value
if the JUnit 5 Platform Engine is present in the project
use junit-platform
if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value
use junit47 provider
if JUnit >= 4.0 is present
use junit4 provider
Expand Down Expand Up @@ -256,11 +258,12 @@ else
<plugins>
[...]
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.11</version>
<configuration>
<groups>com.mycompany.SlowTests</groups>
</configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<groups>com.mycompany.SlowTests</groups>
</configuration>
</plugin>
[...]
</plugins>
Expand Down
5 changes: 3 additions & 2 deletions maven-surefire-plugin/src/site/apt/examples/providers.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Selecting Providers
override such a selection. This can be done by adding the required provider as a dependency to
the surefire-plugin.

The following example shows how to force usage of the Junit 4.7 provider:
The following example shows how to force usage of the JUnit 4.7 provider:

+---+
<plugins>
Expand All @@ -56,7 +56,8 @@ Selecting Providers
</plugins>
+---+

The providers supplied with Surefire are <<<surefire-junit3>>>, <<<surefire-junit4>>>, <<<surefire-junit47>>> and <<<surefire-testng>>>.
The providers supplied with Surefire are <<<surefire-junit3>>>, <<<surefire-junit4>>>, <<<surefire-junit47>>>,
<<<surefire-junit-platform>>> and <<<surefire-testng>>>.
Please note that forcing a provider still requires that the test framework is properly set up on your project classpath.

You can also specify multiple providers as dependencies, and they will all be run and produce a common report.
Expand Down
Loading