You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/02/16 11:38:56 UTC

[maven-surefire] 01/02: [SUREFIRE-1585] Align JUnit Platform version at runtime

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch SUREFIRE-1585-tibor2
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit f33943fc5f9dc0fd796ea9a93142d74cd417b626
Author: tibordigana <ti...@apache.org>
AuthorDate: Thu Feb 14 22:04:10 2019 +0100

    [SUREFIRE-1585] Align JUnit Platform version at runtime
---
 .../plugin/surefire/AbstractSurefireMojo.java      |  58 +--
 .../plugin/surefire/AbstractSurefireMojoTest.java  | 443 +++++++++++++++++++++
 2 files changed, 478 insertions(+), 23 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 f2a4a91..90fc075 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
@@ -847,6 +847,11 @@ public abstract class AbstractSurefireMojo
         }
     }
 
+    void setLogger( Logger logger )
+    {
+        this.logger = logger;
+    }
+
     @Nonnull
     protected final PluginConsoleLogger getConsoleLogger()
     {
@@ -988,8 +993,8 @@ public abstract class AbstractSurefireMojo
     private void executeAfterPreconditionsChecked( @Nonnull DefaultScanResult scanResult )
         throws MojoExecutionException, MojoFailureException
     {
-        TestClassPath testClasspathWrapper = generateTestClasspath();
-        List<ProviderInfo> providers = createProviders( testClasspathWrapper );
+        TestClassPath testClasspath = generateTestClasspath();
+        List<ProviderInfo> providers = createProviders( testClasspath );
 
         RunResult current = noTestsRun();
 
@@ -998,7 +1003,7 @@ public abstract class AbstractSurefireMojo
         {
             try
             {
-                current = current.aggregate( executeProvider( provider, scanResult, testClasspathWrapper ) );
+                current = current.aggregate( executeProvider( provider, scanResult, testClasspath ) );
             }
             catch ( SurefireBooterForkException | SurefireExecutionException | TestSetFailedException e )
             {
@@ -1026,13 +1031,13 @@ public abstract class AbstractSurefireMojo
                                                                    getPluginName() );
     }
 
-    protected List<ProviderInfo> createProviders( TestClassPath testClasspathWrapper )
+    protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
         throws MojoExecutionException
     {
         Artifact junitDepArtifact = getJunitDepArtifact();
         return new ProviderList( new DynamicProviderInfo( null ),
                               new TestNgProviderInfo( getTestNgArtifact() ),
-                              new JUnitPlatformProviderInfo( getJunitPlatformArtifact(), testClasspathWrapper ),
+                              new JUnitPlatformProviderInfo( getJunitPlatformArtifact(), testClasspath ),
                               new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit3ProviderInfo() )
@@ -2128,7 +2133,6 @@ public abstract class AbstractSurefireMojo
         return getProjectArtifactMap().get( "junit:junit-dep" );
     }
 
-
     private Artifact getJunitPlatformArtifact()
     {
         Artifact artifact = getProjectArtifactMap().get( getJunitPlatformArtifactName() );
@@ -2878,12 +2882,12 @@ public abstract class AbstractSurefireMojo
         private static final String PROVIDER_DEP_AID = "junit-platform-launcher";
 
         private final Artifact junitPlatformArtifact;
-        private final TestClassPath testClasspathWrapper;
+        private final TestClassPath testClasspath;
 
-        JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, TestClassPath testClasspathWrapper )
+        JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, TestClassPath testClasspath )
         {
             this.junitPlatformArtifact = junitPlatformArtifact;
-            this.testClasspathWrapper = testClasspathWrapper;
+            this.testClasspath = testClasspath;
         }
 
         @Override
@@ -2912,14 +2916,20 @@ public abstract class AbstractSurefireMojo
             String surefireVersion = surefireBooterArtifact.getBaseVersion();
             Map<String, Artifact> providerArtifacts =
                     dependencyResolver.getProviderClasspathAsMap( "surefire-junit-platform", surefireVersion );
-            Map<String, Artifact> testDependencies = testClasspathWrapper.getTestDependencies();
-
+            Map<String, Artifact> testDependencies = testClasspath.getTestDependencies();
+            // pozri hore ten parameter pre junit-platform-engine premenuj hodnotu na junit-platform-commons
             if ( hasDependencyPlatformEngine( testDependencies ) )
             {
                 String filterTestDependency = "org.junit.platform:junit-platform-engine";
                 logDebugOrCliShowErrors( "Test dependencies contain " + filterTestDependency );
                 narrowProviderDependencies( filterTestDependency, providerArtifacts, testDependencies );
             }
+            else if ( hasDependencyPlatformCommons( testDependencies ) )
+            {
+                String filterTestDependency = "org.junit.platform:junit-platform-commons";
+                logDebugOrCliShowErrors( "Test dependencies contain " + filterTestDependency );
+                narrowProviderDependencies( filterTestDependency, providerArtifacts, testDependencies );
+            }
             else if ( hasDependencyJupiterAPI( testDependencies ) )
             {
                 String api = "org.junit.jupiter:junit-jupiter-api";
@@ -2929,12 +2939,10 @@ public abstract class AbstractSurefireMojo
                 addEngineByApi( api, engineGroupId, engineArtifactId, providerArtifacts, testDependencies );
                 alignVersions( version, providerArtifacts, testDependencies );
             }
-            else if ( hasDependencyJUnit4( testDependencies ) )
+            /*else if ( hasDependencyJUnit4( testDependencies ) )
             {
-                String version = testDependencies.get( "junit:junit" ).getBaseVersion();
                 addEngineByApi( "junit:junit", "junit", "junit", providerArtifacts, testDependencies );
-                alignVersions( version, providerArtifacts, testDependencies );
-            }
+            }*/
             return new LinkedHashSet<>( providerArtifacts.values() );
         }
 
@@ -2943,14 +2951,14 @@ public abstract class AbstractSurefireMojo
                                      Map<String, Artifact> providerArtifacts,
                                      Map<String, Artifact> testDependencies )
         {
-            String jupiterVersion = testDependencies.get( api ).getBaseVersion();
+            String version = testDependencies.get( api ).getBaseVersion();
             narrowProviderDependencies( api, providerArtifacts, testDependencies );
-            for ( Artifact jupiterDep : resolve( engineGroupId, engineArtifactId, jupiterVersion, null, "jar" ) )
+            for ( Artifact dep : resolve( engineGroupId, engineArtifactId, version, null, "jar" ) )
             {
-                String key = jupiterDep.getGroupId() + ":" + jupiterDep.getArtifactId();
-                if ( !testDependencies.containsKey( key ) )
+                String key = dep.getGroupId() + ":" + dep.getArtifactId();
+                if ( testDependencies.remove( key ) != null )
                 {
-                    providerArtifacts.put( key, jupiterDep );
+                    providerArtifacts.put( key, dep );
                 }
             }
         }
@@ -2968,8 +2976,8 @@ public abstract class AbstractSurefireMojo
             for ( Artifact engineDep : resolve( groupId, artifactId, version, classifier, type ) )
             {
                 providerArtifacts.remove( engineDep.getGroupId() + ":" + engineDep.getArtifactId() );
-                logDebugOrCliShowErrors( "Removed artifact " + engineDep + " from provider. "
-                        + "Already appears in test classpath." );
+                logDebugOrCliShowErrors( "Removed artifact " + engineDep
+                        + " from provider. Already appears in test classpath." );
             }
             alignVersions( version, providerArtifacts, testDependencies );
         }
@@ -3008,6 +3016,11 @@ public abstract class AbstractSurefireMojo
             return providerArtifacts.containsKey( "org.junit.jupiter:junit-jupiter-api" );
         }
 
+        private boolean hasDependencyPlatformCommons( Map<String, Artifact> providerArtifacts )
+        {
+            return providerArtifacts.containsKey( "org.junit.platform:junit-platform-commons" );
+        }
+
         private boolean hasDependencyPlatformEngine( Map<String, Artifact> providerArtifacts )
         {
             return providerArtifacts.containsKey( "org.junit.platform:junit-platform-engine" );
@@ -3289,7 +3302,6 @@ public abstract class AbstractSurefireMojo
         this.projectArtifactMap = projectArtifactMap;
     }
 
-
     public String getReportNameSuffix()
     {
         return reportNameSuffix;
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
index c9a332a..016eef8 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
@@ -22,18 +22,27 @@ package org.apache.maven.plugin.surefire;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.surefire.AbstractSurefireMojo.JUnitPlatformProviderInfo;
 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.repository.RepositorySystem;
 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.StartupConfiguration;
 import org.apache.maven.surefire.suite.RunResult;
 import org.codehaus.plexus.logging.Logger;
+import org.fest.assertions.MapAssert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -41,6 +50,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -51,10 +61,13 @@ import java.util.Set;
 import static java.io.File.separatorChar;
 import static java.util.Arrays.asList;
 import static java.util.Collections.singleton;
+import static java.util.Collections.singletonMap;
 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
 import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.MapAssert.entry;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.times;
@@ -359,9 +372,439 @@ public class AbstractSurefireMojoTest
                 .isDirectory();
     }
 
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit4() throws Exception
+    {
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Artifact testClasspathJUnit = new DefaultArtifact( "junit", "junit", createFromVersion( "4.12" ), null, "jar",
+                null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = singleton( testClasspathJUnit );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+        final ArtifactResolutionResult surefireProviderResolutionResult = mock( ArtifactResolutionResult.class );
+        final ArtifactResolutionResult junit4ResolutionResult = mock( ArtifactResolutionResult.class );
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact artifact = req.getArtifact();
+                        if ( artifact == surefireProvider )
+                        {
+                            return surefireProviderResolutionResult;
+                        }
+                        else if ( artifact.getGroupId().equals( "junit" )
+                                && artifact.getArtifactId().equals( "junit" )
+                                && artifact.getVersion().equals( "4.12" ) )
+                        {
+                            return junit4ResolutionResult;
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> providerArtifacts = new HashSet<>();
+        providerArtifacts.add( surefireProvider );
+        providerArtifacts.add( java5 );
+        providerArtifacts.add( launcher );
+        providerArtifacts.add( apiguardian );
+        providerArtifacts.add( engine );
+        providerArtifacts.add( commons );
+        providerArtifacts.add( opentest4j );
+
+        when( surefireProviderResolutionResult.getArtifacts() )
+                .thenReturn( providerArtifacts );
+
+        Artifact junit = new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact hamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> junitArtifacts = new HashSet<>();
+        junitArtifacts.add( junit );
+        junitArtifacts.add( hamcrest );
+        when( junit4ResolutionResult.getArtifacts() )
+                .thenReturn( junitArtifacts );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        Artifact expectedProvider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedCommonJava5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedLauncher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedJUnit5Engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedPlatformCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( prov.getProviderClasspath() )
+                .hasSize( 7 )
+                .containsOnly( expectedProvider, expectedCommonJava5, expectedLauncher, expectedApiguardian,
+                        expectedJUnit5Engine, expectedOpentest4j, expectedPlatformCommons );
+
+        Artifact expectedJUnit = new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 1 )
+                .includes( entry( "junit:junit", expectedJUnit ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Commons() throws Exception
+    {
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", "", mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", "", null );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", "", null );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", "", mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts =
+                asList( testClasspathSomeTestArtifact, testClasspathApiguardian, testClasspathCommons );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", "", null );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", "", null );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        if ( req.getArtifact() == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( req.getArtifact().equals( testClasspathCommons )  )
+                        {
+                            return createTestClasspathCommonsResolutionResult( testClasspathSomeTestArtifact, null,
+                                    testClasspathApiguardian, testClasspathCommons, null );
+                        }
+                        else if ( "org.junit.platform".equals( req.getArtifact().getGroupId() )
+                                && "junit-platform-launcher".equals( req.getArtifact().getArtifactId() )
+                                && "1.4.0".equals( req.getArtifact().getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", "", null );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", "", null );
+        Artifact testClasspathJUnit5 = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", "", null );
+        Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", "", null );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 5 )
+                .containsOnly( surefireProvider, java5, launcher, testClasspathJUnit5, testClasspathOpentest4j );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Engine() throws Exception
+    {
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", "", mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", "", null );
+
+        final Artifact testClasspathJUnit5 = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", "", null );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", "", null );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", "", mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", "", null );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJUnit5,
+                testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", "", null );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", "", null );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        if ( req.getArtifact() == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( req.getArtifact().equals( testClasspathJUnit5 )  )
+                        {
+                            return createTestClasspathCommonsResolutionResult( testClasspathSomeTestArtifact,
+                                    testClasspathJUnit5, testClasspathApiguardian, testClasspathCommons,
+                                    testClasspathOpentest4j );
+                        }
+                        else if ( "org.junit.platform".equals( req.getArtifact().getGroupId() )
+                                && "junit-platform-launcher".equals( req.getArtifact().getArtifactId() )
+                                && "1.4.0".equals( req.getArtifact().getVersion() ) )
+                        {
+                            return createJUnitPlatformLauncherResolutionResult( testClasspathJUnit5,
+                                    testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", "", null );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", "", null );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 3 )
+                .containsOnly( surefireProvider, java5, launcher );
+    }
+
+    private static ArtifactResolutionResult createJUnitPlatformLauncherResolutionResult(
+            Artifact junit5Engine, Artifact apiguardian, Artifact commons, Artifact opentest4j )
+    {
+        ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                commons.getVersionRange(), null, "jar", "", null );
+        resolvedLauncherArtifacts.add( launcher );
+        resolvedLauncherArtifacts.add( apiguardian );
+        resolvedLauncherArtifacts.add( junit5Engine );
+        resolvedLauncherArtifacts.add( commons );
+        resolvedLauncherArtifacts.add( opentest4j );
+        resolvedLauncherArtifacts.remove( null );
+        when( launcherResolutionResult.getArtifacts() )
+                .thenReturn( resolvedLauncherArtifacts );
+        return launcherResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createExpectedJUnitPlatformLauncherResolutionResult()
+    {
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", "", mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", "", mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", "", null );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", "", mock( ArtifactHandler.class ) );
+        return createJUnitPlatformLauncherResolutionResult( engine, apiguardian, commons, opentest4j );
+    }
+
+    private static ArtifactResolutionResult createTestClasspathCommonsResolutionResult(
+            Artifact testClasspathSomeTestArtifact, Artifact testClasspathJUnit5, Artifact testClasspathApiguardian,
+            Artifact testClasspathCommons, Artifact testClasspathOpentest4j )
+    {
+        ArtifactResolutionResult testClasspathCommonsResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedCommonsArtifacts = new HashSet<>();
+        resolvedCommonsArtifacts.add( testClasspathSomeTestArtifact );
+        resolvedCommonsArtifacts.add( testClasspathApiguardian );
+        resolvedCommonsArtifacts.add( testClasspathCommons );
+        resolvedCommonsArtifacts.add( testClasspathJUnit5 );
+        resolvedCommonsArtifacts.add( testClasspathOpentest4j );
+        resolvedCommonsArtifacts.remove( null );
+        when( testClasspathCommonsResolutionResult.getArtifacts() )
+                .thenReturn( resolvedCommonsArtifacts );
+        return testClasspathCommonsResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createSurefireProviderResolutionResult( VersionRange surefireVersion )
+    {
+        ArtifactResolutionResult surefirePlatformResolutionResult = mock( ArtifactResolutionResult.class );
+
+        Artifact provider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", "", null );
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", "", null );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", "", null );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", "", null );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", "", null );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", "", null );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", "", null );
+
+        Set<Artifact> providerArtifacts = new HashSet<>();
+        providerArtifacts.add( provider );
+        providerArtifacts.add( java5 );
+        providerArtifacts.add( launcher );
+        providerArtifacts.add( apiguardian );
+        providerArtifacts.add( engine );
+        providerArtifacts.add( commons );
+        providerArtifacts.add( opentest4j );
+
+        when( surefirePlatformResolutionResult.getArtifacts() )
+                .thenReturn( providerArtifacts );
+        return surefirePlatformResolutionResult;
+    }
+
     public static class Mojo
             extends AbstractSurefireMojo
     {
+        private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo( Artifact junitPlatformArtifact,
+                                                                           TestClassPath testClasspathWrapper )
+        {
+            return new JUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        }
+
+        @Override
+        protected void logDebugOrCliShowErrors( String s )
+        {
+            // do nothing
+        }
+
         @Override
         protected String getPluginName()
         {