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 2020/05/11 09:49:02 UTC

[maven-surefire] 02/02: [SUREFIRE-1787] Support multiple runners (JUnit4, TestNG, other) and their API in JUnit5 Provider

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

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

commit d5bbb3f9ae37ff5ad2bb7e8b3c11d1f24ea6f041
Author: tibordigana <ti...@apache.org>
AuthorDate: Sat May 2 13:08:16 2020 +0200

    [SUREFIRE-1787] Support multiple runners (JUnit4, TestNG, other) and their API in JUnit5 Provider
---
 .../plugin/surefire/AbstractSurefireMojo.java      | 140 ++---
 .../surefire/SurefireDependencyResolver.java       |  26 +-
 .../plugin/surefire/AbstractSurefireMojoTest.java  | 629 ++++++++++++---------
 .../surefire/SurefireDependencyResolverTest.java   |   9 +-
 .../src/site/apt/examples/junit-platform.apt.vm    | 241 +++++++-
 pom.xml                                            |   2 +-
 .../surefire/its/jiras/Surefire1787JUnit5IT.java   | 122 ++++
 surefire-its/src/test/resources/junit-4-5/pom.xml  | 166 ++++++
 .../junit-4-5/src/test/java/pkg/JUnit4Test.java    |  10 +
 .../junit-4-5/src/test/java/pkg/JUnit5Test.java    |  10 +
 .../src/test/resources/junit5-runner/pom.xml       |  66 +++
 .../src/test/java/examples/RootTest.java           |  10 +
 .../src/test/java/examples/a/ATest.java            |  10 +
 .../src/test/java/examples/b/BTest.java            |  10 +
 .../src/test/java/pkg/JUnit5Tests.java             |  15 +
 .../src/test/resources/junit5-testng/pom.xml       |  94 +++
 .../src/test/java/pkg/JUnit5Test.java              |  10 +
 .../src/test/java/pkg/TestNGTest.java              |  10 +
 18 files changed, 1202 insertions(+), 378 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 6fd5df4..9fa9d88 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
@@ -119,6 +119,7 @@ import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 
 import static java.lang.Boolean.TRUE;
+import static java.lang.Integer.parseInt;
 import static java.lang.Thread.currentThread;
 import static java.util.Arrays.asList;
 import static java.util.Collections.addAll;
@@ -126,7 +127,6 @@ import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonMap;
 import static org.apache.maven.surefire.shared.lang3.StringUtils.substringBeforeLast;
 import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
-import static org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId;
 import static org.apache.maven.plugin.surefire.SurefireDependencyResolver.isWithinVersionSpec;
 import static org.apache.maven.plugin.surefire.util.DependencyScanner.filter;
 import static org.apache.maven.plugin.surefire.SurefireHelper.replaceThreadNumberPlaceholders;
@@ -1173,8 +1173,8 @@ public abstract class AbstractSurefireMojo
     {
         Artifact junitDepArtifact = getJunitDepArtifact();
         return new ProviderList( new DynamicProviderInfo( null ),
+                              new JUnitPlatformProviderInfo( getJUnit5Artifact(), testClasspath ),
                               new TestNgProviderInfo( getTestNgArtifact() ),
-                              new JUnitPlatformProviderInfo( getJunitPlatformArtifact(), testClasspath ),
                               new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit3ProviderInfo() )
@@ -2308,21 +2308,17 @@ public abstract class AbstractSurefireMojo
         return getProjectArtifactMap().get( "junit:junit-dep" );
     }
 
-    private Artifact getJunitPlatformArtifact()
+    private Artifact getJUnit5Artifact()
     {
-        Artifact artifact = getProjectArtifactMap().get( "org.junit.platform:junit-platform-commons" );
-        if ( artifact == null )
+        if ( getProjectArtifactMap().get( "org.junit.platform:junit-platform-runner" ) != null )
         {
-            artifact = getPluginArtifactMap().get( "org.junit.platform:junit-platform-engine" );
+            return null;
         }
 
-        Artifact projectArtifact = project.getArtifact();
-        String projectGroupId = projectArtifact.getGroupId();
-        if ( artifact == null && ( "org.junit.platform".equals( projectGroupId )
-                || "org.junit.jupiter".equals( projectGroupId )
-                || "org.junit.vintage".equals( projectGroupId ) ) )
+        Artifact artifact = getPluginArtifactMap().get( "org.junit.platform:junit-platform-engine" );
+        if ( artifact == null )
         {
-            artifact = projectArtifact;
+            return getProjectArtifactMap().get( "org.junit.platform:junit-platform-commons" );
         }
 
         return artifact;
@@ -2503,7 +2499,7 @@ public abstract class AbstractSurefireMojo
         }
         else
         {
-            return Integer.parseInt( trimmed );
+            return parseInt( trimmed );
         }
     }
 
@@ -2890,7 +2886,7 @@ public abstract class AbstractSurefireMojo
             {
                 Artifact junitArtifact = getJunitArtifact();
                 boolean junit47Compatible = isJunit47Compatible( junitArtifact );
-                boolean junit5PlatformCompatible = getJunitPlatformArtifact() != null;
+                boolean junit5PlatformCompatible = getJUnit5Artifact() != null;
                 if ( !junit47Compatible && !junit5PlatformCompatible )
                 {
                     if ( junitArtifact != null )
@@ -3108,7 +3104,7 @@ public abstract class AbstractSurefireMojo
         private final Artifact junitPlatformArtifact;
         private final TestClassPath testClasspath;
 
-        JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, TestClassPath testClasspath )
+        JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, @Nonnull TestClassPath testClasspath )
         {
             this.junitPlatformArtifact = junitPlatformArtifact;
             this.testClasspath = testClasspath;
@@ -3140,79 +3136,74 @@ public abstract class AbstractSurefireMojo
             String surefireVersion = getBooterArtifact().getBaseVersion();
             Map<String, Artifact> providerArtifacts =
                     surefireDependencyResolver.getProviderClasspathAsMap( "surefire-junit-platform", surefireVersion );
-            Map<String, Artifact> testDependencies = testClasspath.getTestDependencies();
+            Map<String, Artifact> testDeps = testClasspath.getTestDependencies();
 
-            if ( hasDependencyPlatformEngine( testDependencies ) )
+            ProjectBuildingRequest request = getSession().getProjectBuildingRequest();
+            Plugin plugin = getPluginDescriptor().getPlugin();
+            Map<String, Artifact> pluginDeps =
+                surefireDependencyResolver.resolvePluginDependencies( request, plugin, getPluginArtifactMap() );
+
+            if ( hasDependencyPlatformEngine( pluginDeps ) )
             {
-                String filterTestDependency = "org.junit.platform:junit-platform-engine";
-                getConsoleLogger().debug( "Test dependencies contain " + filterTestDependency );
-                narrowProviderDependencies( filterTestDependency, providerArtifacts, testDependencies );
+                providerArtifacts.putAll( pluginDeps );
             }
             else
             {
-                ProjectBuildingRequest request = getSession().getProjectBuildingRequest();
-                Plugin plugin = getPluginDescriptor().getPlugin();
-                Set<Artifact> engines = surefireDependencyResolver.resolvePluginDependencies( request, plugin );
-                if ( hasDependencyPlatformEngine( engines ) )
-                {
-                    Map<String, Artifact> engineArtifacts = artifactMapByVersionlessId( engines );
-                    providerArtifacts.putAll( engineArtifacts );
-                    alignVersions( providerArtifacts, engineArtifacts );
-                }
-                else if ( hasDependencyJupiterAPI( testDependencies ) )
+                String engineVersion = null;
+                if ( hasDependencyJupiterAPI( testDeps )
+                    && !testDeps.containsKey( "org.junit.jupiter:junit-jupiter-engine" ) )
                 {
                     String engineGroupId = "org.junit.jupiter";
                     String engineArtifactId = "junit-jupiter-engine";
                     String engineCoordinates = engineGroupId + ":" + engineArtifactId;
                     String api = "org.junit.jupiter:junit-jupiter-api";
-                    getConsoleLogger().debug( "Test dependencies contain " + api + ". Resolving " + engineCoordinates );
-                    String engineVersion = testDependencies.get( api ).getBaseVersion();
-                    addEngineByApi( engineGroupId, engineArtifactId, engineVersion,
-                            providerArtifacts, testDependencies );
+                    engineVersion = testDeps.get( api ).getBaseVersion();
+                    getConsoleLogger().debug( "Test dependencies contain "
+                        + api + ". Resolving " + engineCoordinates + ":" + engineVersion );
+                    addEngineByApi( engineGroupId, engineArtifactId, engineVersion, providerArtifacts );
+                }
+
+                if ( ( testDeps.containsKey( "junit:junit" ) || testDeps.containsKey( "junit:junit-dep" ) )
+                    && !testDeps.containsKey( "org.junit.vintage:junit-vintage-engine" ) )
+                {
+                    String engineGroupId = "org.junit.vintage";
+                    String engineArtifactId = "junit-vintage-engine";
+                    String engineCoordinates = engineGroupId + ":" + engineArtifactId;
+
+                    if ( engineVersion != null )
+                    {
+                        getConsoleLogger().debug( "Test dependencies contain JUnit4. Resolving "
+                            + engineCoordinates + ":" + engineVersion );
+                        addEngineByApi( engineGroupId, engineArtifactId, engineVersion, providerArtifacts );
+                    }
                 }
             }
-            providerArtifacts.keySet().removeAll( testDependencies.keySet() );
+
+            narrowDependencies( providerArtifacts, testDeps );
+            alignProviderVersions( providerArtifacts );
+
             return new LinkedHashSet<>( providerArtifacts.values() );
         }
 
         private void addEngineByApi( String engineGroupId, String engineArtifactId, String engineVersion,
-                                     Map<String, Artifact> providerArtifacts, Map<String, Artifact> testDependencies )
+                                     Map<String, Artifact> providerArtifacts )
         {
-            providerArtifacts.keySet().removeAll( testDependencies.keySet() );
             for ( Artifact dep : resolve( engineGroupId, engineArtifactId, engineVersion, null, "jar" ) )
             {
                 String key = dep.getGroupId() + ":" + dep.getArtifactId();
-                if ( !testDependencies.containsKey( key ) )
-                {
-                    providerArtifacts.put( key, dep );
-                }
+                providerArtifacts.put( key, dep );
             }
-            alignVersions( providerArtifacts, testDependencies );
         }
 
-        private void narrowProviderDependencies( String filterTestDependency,
-                                                 Map<String, Artifact> providerArtifacts,
-                                                 Map<String, Artifact> testDependencies )
+        private void narrowDependencies( Map<String, Artifact> providerArtifacts,
+                                         Map<String, Artifact> testDependencies )
         {
-            Artifact engine = testDependencies.get( filterTestDependency );
-            String groupId = engine.getGroupId();
-            String artifactId = engine.getArtifactId();
-            String version = engine.getBaseVersion();
-            String classifier = engine.getClassifier();
-            String type = engine.getType();
-            for ( Artifact engineDep : resolve( groupId, artifactId, version, classifier, type ) )
-            {
-                providerArtifacts.remove( engineDep.getGroupId() + ":" + engineDep.getArtifactId() );
-                getConsoleLogger().debug( "Removed artifact " + engineDep
-                        + " from provider. Already appears in test classpath." );
-            }
-            alignVersions( providerArtifacts, testDependencies );
+            providerArtifacts.keySet().removeAll( testDependencies.keySet() );
         }
 
-        private void alignVersions( Map<String, Artifact> providerArtifacts,
-                                    Map<String, Artifact> referencedDependencies )
+        private void alignProviderVersions( Map<String, Artifact> providerArtifacts )
         {
-            String version = referencedDependencies.get( "org.junit.platform:junit-platform-commons" ).getBaseVersion();
+            String version = junitPlatformArtifact.getBaseVersion();
             for ( Artifact launcherArtifact : resolve( PROVIDER_DEP_GID, PROVIDER_DEP_AID, version, null, "jar" ) )
             {
                 String key = launcherArtifact.getGroupId() + ":" + launcherArtifact.getArtifactId();
@@ -3235,27 +3226,14 @@ public abstract class AbstractSurefireMojo
 
         private boolean hasDependencyJupiterAPI( Map<String, Artifact> dependencies )
         {
-            return dependencies.containsKey( "org.junit.jupiter:junit-jupiter-api" )
-                    || hasGroupArtifactId( "org.junit.jupiter", "junit-jupiter-api", getProject().getArtifact() );
+            return dependencies.containsKey( "org.junit.jupiter:junit-jupiter-api" );
         }
 
         private boolean hasDependencyPlatformEngine( Map<String, Artifact> dependencies )
         {
-            return dependencies.containsKey( "org.junit.platform:junit-platform-engine" )
-                    || hasGroupArtifactId( "org.junit.platform", "junit-platform-engine", getProject().getArtifact() );
-        }
-
-        private boolean hasDependencyPlatformEngine( Collection<Artifact> dependencies )
-        {
-            if ( hasGroupArtifactId( "org.junit.platform", "junit-platform-engine", getProject().getArtifact() ) )
-            {
-                return true;
-            }
-
-            for ( Artifact dependency : dependencies )
+            for ( Entry<String, Artifact> dependency : dependencies.entrySet() )
             {
-                if ( dependency.getGroupId().equals( "org.junit.platform" )
-                        && dependency.getArtifactId().equals( "junit-platform-engine" ) )
+                if ( dependency.getKey().equals( "org.junit.platform:junit-platform-engine" ) )
                 {
                     return true;
                 }
@@ -3359,7 +3337,9 @@ public abstract class AbstractSurefireMojo
         {
             ProjectBuildingRequest request = getSession().getProjectBuildingRequest();
             Plugin plugin = getPluginDescriptor().getPlugin();
-            return surefireDependencyResolver.resolvePluginDependencies( request, plugin );
+            Map<String, Artifact> providerArtifacts =
+                surefireDependencyResolver.resolvePluginDependencies( request, plugin, getPluginArtifactMap() );
+            return new LinkedHashSet<>( providerArtifacts.values() );
         }
     }
 
@@ -3389,10 +3369,10 @@ public abstract class AbstractSurefireMojo
                 logDebugOrCliShowErrors( "Using configured provider " + providerToAdd.getProviderName() );
                 providersToRun.add( providerToAdd );
             }
-            return manuallyConfiguredProviders.isEmpty() ? autoDetectOneProvider() : providersToRun;
+            return manuallyConfiguredProviders.isEmpty() ? autoDetectOneWellKnownProvider() : providersToRun;
         }
 
-        @Nonnull private List<ProviderInfo> autoDetectOneProvider()
+        @Nonnull private List<ProviderInfo> autoDetectOneWellKnownProvider()
         {
             List<ProviderInfo> providersToRun = new ArrayList<>();
             for ( ProviderInfo wellKnownProvider : wellKnownProviders )
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
index 6da4a1a..b6ce700 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
@@ -21,6 +21,7 @@ package org.apache.maven.plugin.surefire;
 
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -94,7 +95,7 @@ final class SurefireDependencyResolver
 
     private final String pluginName;
 
-    private final DependencyResolver depencencyResolver;
+    private final DependencyResolver dependencyResolver;
 
     private final boolean offline;
 
@@ -102,7 +103,7 @@ final class SurefireDependencyResolver
                                 ArtifactRepository localRepository,
                                 List<ArtifactRepository> pluginRemoteRepositories,
                                 List<ArtifactRepository> projectRemoteRepositories, String pluginName,
-                                DependencyResolver depencencyResolver, boolean offline )
+                                DependencyResolver dependencyResolver, boolean offline )
     {
         this.repositorySystem = repositorySystem;
         this.log = log;
@@ -110,7 +111,7 @@ final class SurefireDependencyResolver
         this.pluginRemoteRepositories = pluginRemoteRepositories;
         this.projectRemoteRepositories = projectRemoteRepositories;
         this.pluginName = pluginName;
-        this.depencencyResolver = depencencyResolver;
+        this.dependencyResolver = dependencyResolver;
         this.offline = offline;
     }
 
@@ -138,19 +139,26 @@ final class SurefireDependencyResolver
         }
     }
 
-    Set<Artifact> resolvePluginDependencies( ProjectBuildingRequest request, Plugin plugin )
+    Map<String, Artifact> resolvePluginDependencies( ProjectBuildingRequest request,
+                                                     Plugin plugin, Map<String, Artifact> pluginResolvedDependencies )
             throws MojoExecutionException
     {
         Collection<Dependency> pluginDependencies = plugin.getDependencies();
         try
         {
-            Iterable<ArtifactResult> resolvedPluginDependencies = depencencyResolver.resolveDependencies( request,
-                pluginDependencies, null, including( SCOPE_COMPILE, SCOPE_COMPILE_PLUS_RUNTIME, SCOPE_RUNTIME ) );
+            Iterable<ArtifactResult> resolvedArtifacts = dependencyResolver.resolveDependencies( request,
+                pluginDependencies, null, including( RuntimeArtifactFilter.SCOPES ) );
 
-            Set<Artifact> resolved = new LinkedHashSet<>();
-            for ( ArtifactResult resolvedPluginDependency : resolvedPluginDependencies )
+            Map<String, Artifact> resolved = new LinkedHashMap<>();
+            for ( ArtifactResult resolvedArtifact : resolvedArtifacts )
             {
-                resolved.add( resolvedPluginDependency.getArtifact() );
+                Artifact artifact = resolvedArtifact.getArtifact();
+                String key = artifact.getGroupId() + ":" + artifact.getArtifactId();
+                Artifact resolvedPluginDependency = pluginResolvedDependencies.get( key );
+                if ( resolvedPluginDependency != null )
+                {
+                    resolved.put( key, artifact );
+                }
             }
             return resolved;
         }
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 a2a8795..7ed96b3 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
@@ -28,6 +28,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.versioning.VersionRange;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
@@ -38,6 +39,7 @@ import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.repository.RepositorySystem;
 import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
+import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 import org.apache.maven.surefire.booter.Classpath;
@@ -52,7 +54,6 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -77,7 +78,7 @@ import static java.io.File.separatorChar;
 import static java.util.Arrays.asList;
 import static java.util.Collections.emptySet;
 import static java.util.Collections.singleton;
-import static java.util.Collections.singletonMap;
+import static java.util.Collections.singletonList;
 import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
@@ -86,7 +87,6 @@ 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.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
@@ -115,10 +115,28 @@ public class AbstractSurefireMojoTest
     private final Mojo mojo = new Mojo();
 
     @Before
-    public void setSession()
+    public void setupMojo()
     {
+        Artifact mojoArtifact = mojo.getMojoArtifact();
+
+        mojo.setPluginArtifactMap( new LinkedHashMap<String, Artifact>() );
+        mojo.getPluginArtifactMap().put( mojoArtifact.getGroupId() + ":" + mojoArtifact.getArtifactId(), mojoArtifact );
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire", "surefire-booter",
+            mojoArtifact.getVersion(), null, "jar", null, mock( ArtifactHandler.class ) );
+        mojo.getPluginArtifactMap().put( "org.apache.maven.surefire:surefire-booter", forkedBooter );
+
+        mojo.setProjectArtifactMap( new LinkedHashMap<String, Artifact>() );
+
         MavenSession session = mock( MavenSession.class );
         mojo.setSession( session );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        Plugin plugin = new Plugin();
+        plugin.setGroupId( mojoArtifact.getGroupId() );
+        plugin.setArtifactId( mojoArtifact.getArtifactId() );
+        plugin.setVersion( mojoArtifact.getVersion() );
+        when( pluginDescriptor.getPlugin() ).thenReturn( plugin );
+        mojo.setPluginDescriptor( pluginDescriptor );
     }
 
     @Test
@@ -552,13 +570,17 @@ public class AbstractSurefireMojoTest
 
         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 ) );
 
-        Artifact testClasspathJUnit = new DefaultArtifact( "junit", "junit", createFromVersion( "4.12" ), null, "jar",
-                null, mock( ArtifactHandler.class ) );
+        Artifact testClasspathHamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+            createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = singleton( testClasspathJUnit );
+        setProjectDepedenciesToMojo( testClasspathJUnit, testClasspathHamcrest );
+
+        Collection<Artifact> testArtifacts = new ArrayList<>();
+        testArtifacts.add( testClasspathJUnit );
+        testArtifacts.add( testClasspathHamcrest );
 
         File classesDirectory = new File( "target/classes" );
 
@@ -567,10 +589,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -588,7 +606,6 @@ public class AbstractSurefireMojoTest
             }
         } );
         final ArtifactResolutionResult surefireProviderResolutionResult = mock( ArtifactResolutionResult.class );
-        final ArtifactResolutionResult junit4ResolutionResult = mock( ArtifactResolutionResult.class );
         when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
                 .thenAnswer( new Answer<ArtifactResolutionResult>()
                 {
@@ -601,35 +618,20 @@ public class AbstractSurefireMojoTest
                         {
                             return surefireProviderResolutionResult;
                         }
-                        else if ( artifact.getGroupId().equals( "junit" )
-                                && artifact.getArtifactId().equals( "junit" )
-                                && artifact.getVersion().equals( "4.12" ) )
+                        else if ( "org.junit.platform".equals( artifact.getGroupId() )
+                            && "junit-platform-launcher".equals( artifact.getArtifactId() )
+                            && "1.4.0".equals( artifact.getVersion() ) )
                         {
-                            return junit4ResolutionResult;
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
                         }
                         else
                         {
-                            fail();
+                            fail( artifact.getGroupId() + ":" + artifact.getArtifactId() );
                             return null;
                         }
                     }
                 } );
 
-        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
-        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
-                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
-                any( TransformableFilter.class ) ) )
-                .thenAnswer( new Answer<Object>()
-                {
-                    @Override
-                    public Object answer( InvocationOnMock invocation )
-                    {
-                        Collection deps = (Collection) invocation.getArguments()[1];
-                        assertThat( deps ).isEmpty();
-                        return emptySet();
-                    }
-                } );
-
         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",
@@ -654,19 +656,56 @@ public class AbstractSurefireMojoTest
         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 );
+        final Artifact pluginDep1 = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+            createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep2 = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+            createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep3 = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+            createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep4 = new DefaultArtifact( "junit", "junit",
+            createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep5 = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+            createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep6 = new DefaultArtifact( "org.opentest4j", "opentest4j",
+            createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDep7 = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+            createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        addPluginDependencies( pluginDep1, pluginDep2, pluginDep3, pluginDep4, pluginDep5, pluginDep6, pluginDep7 );
 
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
-        mojo.setDependencyResolver( dependencyResolver );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).hasSize( 1 );
+                Dependency pluginDependency = dependencies.iterator().next();
+                assertThat( pluginDependency.getGroupId() ).isEqualTo( "org.junit.vintage" );
+                assertThat( pluginDependency.getArtifactId() ).isEqualTo( "junit-vintage-engine" );
+                assertThat( pluginDependency.getVersion() ).isEqualTo( "5.4.0" );
+
+                Collection<ArtifactResult> it = new ArrayList<>();
+                it.add( toArtifactResult( pluginDep1 ) );
+                it.add( toArtifactResult( pluginDep2 ) );
+                it.add( toArtifactResult( pluginDep3 ) );
+                it.add( toArtifactResult( pluginDep4 ) );
+                it.add( toArtifactResult( pluginDep5 ) );
+                it.add( toArtifactResult( pluginDep6 ) );
+                it.add( toArtifactResult( pluginDep7 ) );
+                return it;
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
 
@@ -678,34 +717,47 @@ public class AbstractSurefireMojoTest
         Plugin p = mock( Plugin.class );
         when( pluginDescriptor.getPlugin() )
                 .thenReturn( p );
+        Artifact pluginDependency = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+            createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
         when( p.getDependencies() )
-                .thenReturn( Collections.<Dependency>emptyList() );
+                .thenReturn( singletonList( toDependency( pluginDependency ) ) );
+
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-engine" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
 
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
 
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         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 ) );
+                createFromVersion( "1.4.0" ), 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 ) );
+                createFromVersion( "1.4.0" ), 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 ) );
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedEngine = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+            createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
         assertThat( prov.getProviderClasspath() )
-                .hasSize( 7 )
+                .hasSize( 8 )
                 .containsOnly( expectedProvider, expectedCommonJava5, expectedLauncher, expectedApiguardian,
-                        expectedJUnit5Engine, expectedOpentest4j, expectedPlatformCommons );
+                        expectedJUnit5Engine, expectedOpentest4j, expectedPlatformCommons, expectedEngine );
 
         assertThat( testClasspathWrapper.getTestDependencies() )
-                .hasSize( 1 )
-                .includes( entry( "junit:junit", testClasspathJUnit ) );
+                .hasSize( 2 )
+                .includes( entry( "junit:junit", testClasspathJUnit ),
+                    entry( "org.hamcrest:hamcrest-core", testClasspathHamcrest ) );
     }
 
     @Test
@@ -716,21 +768,18 @@ public class AbstractSurefireMojoTest
                 null, "jar", null, mock( ArtifactHandler.class ) ) );
         mojo.setProject( mavenProject );
 
-        final VersionRange surefireVersion = createFromVersion( "1" );
+        VersionRange surefireVersion = createFromVersion( "1" );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
-                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
-
-        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+        Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathVintage = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+        Artifact testClasspathVintage = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
                 createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+        Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
                 createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathPlatformEng = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+        Artifact testClasspathPlatformEng = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
                 createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
         Artifact testClasspathJUnit4 = new DefaultArtifact( "junit", "junit",
@@ -739,16 +788,18 @@ public class AbstractSurefireMojoTest
         Artifact testClasspathHamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
                 createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+        Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+        Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
                 createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathVintage,
+        Collection<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathVintage,
                 testClasspathApiguardian, testClasspathPlatformEng, testClasspathJUnit4, testClasspathHamcrest,
                 testClasspathOpentest4j, testClasspathCommons );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -756,10 +807,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -777,7 +824,6 @@ public class AbstractSurefireMojoTest
             }
         } );
         final ArtifactResolutionResult surefireProviderResolutionResult = mock( ArtifactResolutionResult.class );
-        final ArtifactResolutionResult junit4ResolutionResult = mock( ArtifactResolutionResult.class );
         when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
                 .thenAnswer( new Answer<ArtifactResolutionResult>()
                 {
@@ -791,12 +837,6 @@ public class AbstractSurefireMojoTest
                             return surefireProviderResolutionResult;
                         }
                         else if ( "org.junit.platform".equals( resolvable.getGroupId() )
-                                && "junit-platform-engine".equals( resolvable.getArtifactId() )
-                                && "1.4.0".equals( resolvable.getVersion() ) )
-                        {
-                            return createVintageEngineResolutionResult();
-                        }
-                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
                                 && "junit-platform-launcher".equals( resolvable.getArtifactId() )
                                 && "1.4.0".equals( resolvable.getVersion() ) )
                         {
@@ -804,7 +844,7 @@ public class AbstractSurefireMojoTest
                         }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
@@ -830,27 +870,45 @@ public class AbstractSurefireMojoTest
         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 ) );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).isEmpty();
+                return emptySet();
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        mojo.setPluginDescriptor( pluginDescriptor );
+        Plugin p = mock( Plugin.class );
+        when( pluginDescriptor.getPlugin() )
+            .thenReturn( p );
+        when( p.getDependencies() )
+            .thenReturn( Collections.<Dependency>emptyList() );
+
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-commons" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
 
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         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",
@@ -883,21 +941,20 @@ public class AbstractSurefireMojoTest
 
         final VersionRange surefireVersion = createFromVersion( "1" );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
-                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
-
-        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+        Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+        Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
                 createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+        Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
                 createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts =
+        Collection<Artifact> testArtifacts =
                 asList( testClasspathSomeTestArtifact, testClasspathApiguardian, testClasspathCommons );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -905,10 +962,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -938,32 +991,34 @@ public class AbstractSurefireMojoTest
                         {
                             return createSurefireProviderResolutionResult( surefireVersion );
                         }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                            && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                            && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
                 } );
 
-        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
-        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
-                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
-                any( TransformableFilter.class ) ) )
-                .thenAnswer( new Answer<Object>()
-                {
-                    @Override
-                    public Object answer( InvocationOnMock invocation )
-                    {
-                        Collection deps = (Collection) invocation.getArguments()[1];
-                        assertThat( deps ).isEmpty();
-                        return emptySet();
-                    }
-                } );
-
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
-        mojo.setDependencyResolver( dependencyResolver );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).isEmpty();
+                return emptySet();
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
 
@@ -978,8 +1033,17 @@ public class AbstractSurefireMojoTest
         when( p.getDependencies() )
                 .thenReturn( Collections.<Dependency>emptyList() );
 
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-commons" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
 
         Artifact provider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
@@ -987,9 +1051,9 @@ public class AbstractSurefireMojoTest
         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 ) );
+                createFromVersion( "1.4.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 ) );
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
         Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
         assertThat( resolvedProviderArtifacts )
@@ -1013,9 +1077,6 @@ public class AbstractSurefireMojoTest
 
         final VersionRange surefireVersion = createFromVersion( "1" );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
-                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
-
         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
@@ -1031,9 +1092,11 @@ public class AbstractSurefireMojoTest
         final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJUnit5,
+        Collection<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJUnit5,
                 testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -1041,10 +1104,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -1074,11 +1133,6 @@ public class AbstractSurefireMojoTest
                         {
                             return createSurefireProviderResolutionResult( surefireVersion );
                         }
-                        else if ( resolvable.equals( testClasspathJUnit5 )  )
-                        {
-                            return createResolutionResult( testClasspathJUnit5, testClasspathApiguardian,
-                                    testClasspathCommons, testClasspathOpentest4j );
-                        }
                         else if ( "org.junit.platform".equals( resolvable.getGroupId() )
                                 && "junit-platform-launcher".equals( resolvable.getArtifactId() )
                                 && "1.4.0".equals( resolvable.getVersion() ) )
@@ -1087,7 +1141,7 @@ public class AbstractSurefireMojoTest
                         }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
@@ -1095,10 +1149,32 @@ public class AbstractSurefireMojoTest
 
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).isEmpty();
+                return emptySet();
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
+
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-commons" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
 
         Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
@@ -1128,9 +1204,6 @@ public class AbstractSurefireMojoTest
 
         final VersionRange surefireVersion = createFromVersion( "1" );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
-                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
-
         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
@@ -1146,9 +1219,11 @@ public class AbstractSurefireMojoTest
         final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
+        Collection<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
                 testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -1156,10 +1231,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -1189,11 +1260,6 @@ public class AbstractSurefireMojoTest
                         {
                             return createSurefireProviderResolutionResult( surefireVersion );
                         }
-                        else if ( resolvable.equals( testClasspathJupiterApi )  )
-                        {
-                            return createResolutionResult( testClasspathJupiterApi, testClasspathApiguardian,
-                                    testClasspathCommons, testClasspathOpentest4j );
-                        }
                         else if ( "org.junit.platform".equals( resolvable.getGroupId() )
                                 && "junit-platform-launcher".equals( resolvable.getArtifactId() )
                                 && "1.4.0".equals( resolvable.getVersion() ) )
@@ -1208,30 +1274,26 @@ public class AbstractSurefireMojoTest
                         }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
                 } );
 
-        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
-        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
-                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
-                any( TransformableFilter.class ) ) )
-                .thenAnswer( new Answer<Object>()
-                {
-                    @Override
-                    public Object answer( InvocationOnMock invocation )
-                    {
-                        Collection deps = (Collection) invocation.getArguments()[1];
-                        assertThat( deps ).isEmpty();
-                        return emptySet();
-                    }
-                } );
-
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
-        mojo.setDependencyResolver( dependencyResolver );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).isEmpty();
+                return emptySet();
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
 
@@ -1246,8 +1308,17 @@ public class AbstractSurefireMojoTest
         when( p.getDependencies() )
                 .thenReturn( Collections.<Dependency>emptyList() );
 
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-commons" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
 
         Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
@@ -1281,9 +1352,6 @@ public class AbstractSurefireMojoTest
 
         final VersionRange surefireVersion = createFromVersion( "1" );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
-                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
-
         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
@@ -1305,10 +1373,12 @@ public class AbstractSurefireMojoTest
         final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterEngine,
+        Collection<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterEngine,
                 testClasspathPlatformEngine, testClasspathJupiterApi, testClasspathApiguardian, testClasspathCommons,
                 testClasspathOpentest4j );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -1316,10 +1386,6 @@ public class AbstractSurefireMojoTest
         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 );
@@ -1349,26 +1415,15 @@ public class AbstractSurefireMojoTest
                         {
                             return createSurefireProviderResolutionResult( surefireVersion );
                         }
-                        else if ( resolvable.equals( testClasspathJupiterApi )  )
-                        {
-                            return createResolutionResult( testClasspathJupiterApi, testClasspathApiguardian,
-                                    testClasspathCommons, testClasspathOpentest4j );
-                        }
                         else if ( "org.junit.platform".equals( resolvable.getGroupId() )
                                 && "junit-platform-launcher".equals( resolvable.getArtifactId() )
                                 && "1.4.0".equals( resolvable.getVersion() ) )
                         {
                             return createExpectedJUnitPlatformLauncherResolutionResult();
                         }
-                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
-                                && "junit-platform-engine".equals( resolvable.getArtifactId() )
-                                && "1.4.0".equals( resolvable.getVersion() ) )
-                        {
-                            return createVintageEngineResolutionResult();
-                        }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
@@ -1376,10 +1431,32 @@ public class AbstractSurefireMojoTest
 
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).isEmpty();
+                return emptySet();
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
+
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-commons" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
 
         Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
@@ -1404,7 +1481,6 @@ public class AbstractSurefireMojoTest
     @Test
     public void shouldSmartlyResolveJUnit5ProviderWithJupiterEngineInPluginDependencies() throws Exception
     {
-
         final VersionRange surefireVersion = createFromVersion( "1" );
 
         final Artifact plugin = new DefaultArtifact( "org.apache.maven.surefire", "maven-surefire-plugin",
@@ -1431,25 +1507,20 @@ public class AbstractSurefireMojoTest
         final Artifact pluginDepOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Map<String, Artifact> pluginDependencies = new HashMap<>();
-        pluginDependencies.put( "org.apache.maven.surefire:maven-surefire-plugin", plugin );
-        pluginDependencies.put( "org.apache.maven.surefire:surefire-booter", forkedBooter );
-        pluginDependencies.put( "org.junit.jupiter:junit-jupiter-engine", pluginDepJupiterEngine );
-        pluginDependencies.put( "org.junit.platform:junit-platform-engine", pluginDepPlatformEngine );
-        pluginDependencies.put( "org.junit.jupiter:junit-jupiter-api", pluginDepJupiterApi );
-        pluginDependencies.put( "org.apiguardian:apiguardian-api", pluginDepApiguardian );
-        pluginDependencies.put( "org.junit.platform:junit-platform-commons", pluginDepCommons );
-        pluginDependencies.put( "org.opentest4j:opentest4j", pluginDepOpentest4j );
-        mojo.setPluginArtifactMap( pluginDependencies );
+        mojo.getPluginArtifactMap().put( "org.apache.maven.surefire:maven-surefire-plugin", plugin );
+        mojo.getPluginArtifactMap().put( "org.apache.maven.surefire:surefire-booter", forkedBooter );
+        mojo.getPluginArtifactMap().put( "org.junit.jupiter:junit-jupiter-engine", pluginDepJupiterEngine );
+        mojo.getPluginArtifactMap().put( "org.junit.platform:junit-platform-engine", pluginDepPlatformEngine );
+        mojo.getPluginArtifactMap().put( "org.junit.jupiter:junit-jupiter-api", pluginDepJupiterApi );
+        mojo.getPluginArtifactMap().put( "org.apiguardian:apiguardian-api", pluginDepApiguardian );
+        mojo.getPluginArtifactMap().put( "org.junit.platform:junit-platform-commons", pluginDepCommons );
+        mojo.getPluginArtifactMap().put( "org.opentest4j:opentest4j", pluginDepOpentest4j );
 
         MavenProject mavenProject = new MavenProject();
         mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
                 null, "jar", null, mock( ArtifactHandler.class ) ) );
         mojo.setProject( mavenProject );
 
-        Artifact junitPlatformArtifact = new DefaultArtifact( "g", "a",
-                createFromVersion( "0" ), null, "jar", null, mock( ArtifactHandler.class ) );
-
         final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
                 createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
@@ -1465,9 +1536,11 @@ public class AbstractSurefireMojoTest
         final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
                 createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
 
-        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
+        Collection<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
                 testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
 
+        setProjectDepedenciesToMojo( testArtifacts.toArray( new Artifact[testArtifacts.size()] ) );
+
         File classesDirectory = new File( "target/classes" );
 
         File testClassesDirectory = new File( "target/test-classes" );
@@ -1510,54 +1583,9 @@ public class AbstractSurefireMojoTest
                         {
                             return createExpectedJUnitPlatformLauncherResolutionResult();
                         }
-                        else if ( "org.apache.maven.surefire".equals( resolvable.getGroupId() )
-                                && "maven-surefire-plugin".equals( resolvable.getArtifactId() )
-                                && "1".equals( resolvable.getVersion() ) )
-                        {
-                            Set<Artifact> pluginItself = new HashSet<>();
-                            pluginItself.add( plugin );
-                            pluginItself.add( forkedBooter );
-                            ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
-                            when( launcherResolutionResult.getArtifacts() )
-                                    .thenReturn( pluginItself );
-                            return launcherResolutionResult;
-                        }
-                        else
-                        {
-                            fail();
-                            return null;
-                        }
-                    }
-                } );
-
-        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
-        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
-                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
-                any( TransformableFilter.class ) ) )
-                .thenAnswer( new Answer<Object>()
-                {
-                    @Override
-                    public Object answer( InvocationOnMock invocation )
-                    {
-                        Collection deps = (Collection) invocation.getArguments()[1];
-                        assertThat( deps ).hasSize( 1 );
-                        Dependency resolvable = (Dependency) deps.iterator().next();
-                        if ( "org.junit.jupiter".equals( resolvable.getGroupId() )
-                                && "junit-jupiter-engine".equals( resolvable.getArtifactId() )
-                                && "5.4.0".equals( resolvable.getVersion() ) )
-                        {
-                            Set<ArtifactResult> resolvedPluginDeps = new HashSet<>();
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterEngine ) );
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepPlatformEngine ) );
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterApi ) );
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepApiguardian ) );
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepCommons ) );
-                            resolvedPluginDeps.add( toArtifactResult( pluginDepOpentest4j ) );
-                            return resolvedPluginDeps;
-                        }
                         else
                         {
-                            fail();
+                            fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
                             return null;
                         }
                     }
@@ -1565,13 +1593,50 @@ public class AbstractSurefireMojoTest
 
         mojo.setRepositorySystem( repositorySystem );
         mojo.setLogger( mock( Logger.class ) );
-        mojo.setDependencyResolver( dependencyResolver );
+        mojo.setDependencyResolver( new DependencyResolverMock()
+        {
+            @Override
+            public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                                 Collection<Dependency> dependencies,
+                                                                 Collection<Dependency> managedDependencies,
+                                                                 TransformableFilter filter )
+            {
+                assertThat( dependencies ).hasSize( 1 );
+                Dependency resolvable = dependencies.iterator().next();
+                if ( "org.junit.jupiter".equals( resolvable.getGroupId() )
+                    && "junit-jupiter-engine".equals( resolvable.getArtifactId() )
+                    && "5.4.0".equals( resolvable.getVersion() ) )
+                {
+                    Set<ArtifactResult> resolvedPluginDeps = new HashSet<>();
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterEngine ) );
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepPlatformEngine ) );
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterApi ) );
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepApiguardian ) );
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepCommons ) );
+                    resolvedPluginDeps.add( toArtifactResult( pluginDepOpentest4j ) );
+                    return resolvedPluginDeps;
+                }
+                else
+                {
+                    fail( resolvable.getGroupId() + ":" + resolvable.getArtifactId() );
+                    return null;
+                }
+            }
+        } );
 
         invokeMethod( mojo, "setupStuff" );
 
+        Artifact junitPlatformArtifact = invokeMethod( mojo, "getJUnit5Artifact" );
+        assertThat( junitPlatformArtifact.getGroupId() ).isEqualTo( "org.junit.platform" );
+        assertThat( junitPlatformArtifact.getArtifactId() ).isEqualTo( "junit-platform-engine" );
+        assertThat( junitPlatformArtifact.getVersion() ).isEqualTo( "1.4.0" );
+
         JUnitPlatformProviderInfo prov =
                 mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
 
+        assertThat( prov.isApplicable() )
+            .isTrue();
+
         when( mojo.getSession().getProjectBuildingRequest() )
                 .thenReturn( mock( ProjectBuildingRequest.class ) );
 
@@ -1625,31 +1690,6 @@ public class AbstractSurefireMojoTest
         return launcherResolutionResult;
     }
 
-    private static ArtifactResolutionResult createVintageEngineResolutionResult()
-    {
-        ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
-        Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
-                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
-                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "junit", "junit",
-                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.hamcrest", "hamcrest-core",
-                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
-                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.apiguardian", "apiguardian-api",
-                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.opentest4j", "opentest4j",
-                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
-                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
-        when( launcherResolutionResult.getArtifacts() )
-                .thenReturn( resolvedLauncherArtifacts );
-        return launcherResolutionResult;
-    }
-
     private static ArtifactResolutionResult createJupiterEngineResolutionResult()
     {
         ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
@@ -1684,16 +1724,6 @@ public class AbstractSurefireMojoTest
         return createJUnitPlatformLauncherResolutionResult( engine, apiguardian, commons, opentest4j );
     }
 
-    private static ArtifactResolutionResult createResolutionResult( Artifact... artifacts )
-    {
-        ArtifactResolutionResult testClasspathCommonsResolutionResult = mock( ArtifactResolutionResult.class );
-        Set<Artifact> resolvedCommonsArtifacts = new HashSet<>();
-        Collections.addAll( resolvedCommonsArtifacts, artifacts );
-        when( testClasspathCommonsResolutionResult.getArtifacts() )
-                .thenReturn( resolvedCommonsArtifacts );
-        return testClasspathCommonsResolutionResult;
-    }
-
     private static ArtifactResolutionResult createSurefireProviderResolutionResult( VersionRange surefireVersion )
     {
         ArtifactResolutionResult surefirePlatformResolutionResult = mock( ArtifactResolutionResult.class );
@@ -1750,16 +1780,34 @@ public class AbstractSurefireMojoTest
         mojo.verifyParameters();
     }
 
+    private void setProjectDepedenciesToMojo( Artifact... deps )
+    {
+        for ( Artifact dep : deps )
+        {
+            mojo.getProjectArtifactMap()
+                .put( dep.getGroupId() + ":" + dep.getArtifactId(), dep );
+        }
+    }
+
+    private void addPluginDependencies( Artifact... deps )
+    {
+        for ( Artifact dep : deps )
+        {
+            mojo.getPluginArtifactMap()
+                .put( dep.getGroupId() + ":" + dep.getArtifactId(), dep );
+        }
+    }
+
     /**
      *
      */
     public static class Mojo
             extends AbstractSurefireMojo implements SurefireReportParameters
     {
-        private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo( Artifact providerArtifact,
+        private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo( Artifact junitPlatformArtifact,
                                                                            TestClassPath testClasspathWrapper )
         {
-            return new JUnitPlatformProviderInfo( providerArtifact, testClasspathWrapper );
+            return new JUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
         }
 
         @Override
@@ -2177,12 +2225,12 @@ public class AbstractSurefireMojoTest
 
         }
 
-        public void setToolchain( Toolchain toolchain ) throws Exception
+        public void setToolchain( Toolchain toolchain )
         {
             setInternalState( this, "toolchain", toolchain );
         }
 
-        public void setJvm( String jvm ) throws Exception
+        public void setJvm( String jvm )
         {
             setInternalState( this, "jvm", jvm );
         }
@@ -2227,6 +2275,25 @@ public class AbstractSurefireMojoTest
             }
         }
         return new AR();
+    }
+
+    private abstract static class DependencyResolverMock implements DependencyResolver
+    {
+        @Override
+        public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
+                                                             DependableCoordinate coordinate,
+                                                             TransformableFilter filter )
+        {
+            fail( "unexpected call of DependencyResolver" );
+            return null;
+        }
 
+        @Override
+        public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest, Model model,
+                                                             TransformableFilter filter )
+        {
+            fail( "unexpected call of DependencyResolver" );
+            return null;
+        }
     }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
index c90a857..6905850 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
@@ -47,10 +47,12 @@ import java.io.File;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
+import java.util.Map;
 import java.util.Set;
 
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
 import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
 import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE_PLUS_RUNTIME;
 import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME;
@@ -325,12 +327,15 @@ public class SurefireDependencyResolverTest
         when( resolutionResult.getArtifacts() )
             .thenReturn( singleton( providerAsArtifact ) );
 
-        Set<Artifact> providers = surefireDependencyResolver.resolvePluginDependencies( request, plugin );
+        Map<String, Artifact> pluginResolvedDependencies =
+            singletonMap( PROVIDER_GROUP_ID + ":surefire-shadefire", providerAsArtifact );
+        Map<String, Artifact> providers =
+            surefireDependencyResolver.resolvePluginDependencies( request, plugin, pluginResolvedDependencies );
 
         verify( depencencyResolver, times( 1 ) )
             .resolveDependencies( request, dep.getValue(), null, filter.getValue() );
 
-        assertThat( providers )
+        assertThat( providers.values() )
             .hasSize( 1 )
             .containsOnly( providerAsArtifact );
 
diff --git a/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm b/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
index d2d49fc..ef5c014 100644
--- a/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
@@ -74,12 +74,25 @@ Using JUnit 5 Platform
   see the {{{https://junit.org/junit5/}JUnit 5 web site}}
   and the {{{https://junit.org/junit5/docs/current/user-guide/}JUnit 5 User Guide}}.
 
-* Smart Resolution of Jupiter Engine and Vintage Engine for JUnit4 (since plugin version 3.0.0-M4)
+* Smart Resolution of Jupiter Engine and Vintage Engine for JUnit4
 
-  JUnit5 API artifact and your test sources become isolated from engine.
+  JUnit5 API artifact and your test sources become isolated from engine. In these chapters you will see how you can
+  segregate, combine, select the APIs and Engines miscellaneous way. You can find integration tests
+  {{{https://github.com/apache/maven-surefire/tree/master/surefire-its/src/test/resources/junit-4-5}with JUnit4/5}},
+  {{{https://github.com/apache/maven-surefire/tree/master/surefire-its/src/test/resources/junit5-testng}with JUnit5/TestNG}}
+  and {{{https://github.com/apache/maven-surefire/tree/master/surefire-its/src/test/resources/junit5-runner}with the JUnit4 Runner for Jupiter tests}}.
+  (See the Maven profiles.)
 
-  Normally the developer does not want to access internal classes of JUnit5 engine (e.g. <<<5.4.0>>>). In this example
-  the POM has only Jupiter API dependency in test classpath.
+** How to run only one API
+
+  Normally, the developer does not want to access internal classes of JUnit5 engine (e.g. <<<5.4.0>>>).
+  In the next chapters you can find your way to use the Jupiter or JUnit5 API where the plugin would resolve the engine.
+
+*** Jupiter API in test dependencies
+
+  In this example the POM has only Jupiter API dependency in test classpath. The plugin will resolve and download
+  the <<<junit-jupiter-engine>>> with the version related to the version of <<<junit-jupiter-api>>>. Similar principles
+  can be found in the following chapters as well.
 
 +---+
 <dependencies>
@@ -108,6 +121,8 @@ Using JUnit 5 Platform
 ...
 +---+
 
+*** API-Engine versions segregation
+
   In the following example the engine artifact appears in plugin dependencies and the engine is resolved by the plugin
   and downloaded from a remote repository for plugins. You may want to update the version of engine with fixed bugs in
   <<<5.3.2>>> but the API version <<<5.3.0>>> stays intact!
@@ -145,8 +160,11 @@ Using JUnit 5 Platform
 ...
 +---+
 
+*** JUnit4 API in test dependencies
 
-  Similar with JUnit4 in test dependencies of your project POM. The Vintage engine artifact is in plugin dependencies.
+  This is similar example with JUnit4 in test dependencies of your project POM.
+  The Vintage engine artifact has to be in the plugin dependencies; otherwise the plugin would use
+  <<<surefire-junit4>>> provider instead of the <<<surefire-junit-platform>>> provider.
 
 +---+
 <dependencies>
@@ -180,6 +198,219 @@ Using JUnit 5 Platform
 ...
 +---+
 
+** How to run multiple APIs or Engines
+
+  In the following example you can use both JUnit4 and JUnit5 tests.
+
+*** Jupiter API and JUnit4
+
+  Once you define any JUnit5 API in the dependencies, the provider <<<surefire-junit-platform>>> is selected and
+  you can always add the JUnit4 dependency.
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
++---+
+
+*** Jupiter API and Vintage Engine
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.junit.vintage</groupId>
+        <artifactId>junit-vintage-engine</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
++---+
+
+*** Jupiter and Vintage Engine
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-engine</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.junit.vintage</groupId>
+        <artifactId>junit-vintage-engine</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
++---+
+
+** Select engine and use multiple APIs
+
+  In these examples you use both API, i.e. Jupiter and JUnit4, in the test dependencies but you want to select
+  the engine via plugin dependencies.
+
+*** Select Jupiter
+
+    Here your tests import the packages from JUnit4 and Jupiter but you want to select only one Maven profile
+    with JUnit4 tests.
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
+<profile>
+    <id>select-junit5</id>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.junit.jupiter</groupId>
+                        <artifactId>junit-jupiter-engine</artifactId>
+                        <version>5.6.2</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</profile>
++---+
+
+*** Select JUnit4
+
+  Here your tests import the packages from JUnit4 and Jupiter but you want to select only one Maven profile
+  with Jupiter tests.
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
+<profile>
+    <id>select-junit4</id>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.junit.vintage</groupId>
+                        <artifactId>junit-vintage-engine</artifactId>
+                        <version>5.6.2</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</profile>
++---+
+
+** How to run TestNG tests within Jupiter engine
+
+  You can run TestNG tests combined with JUnit5 tests.
+
+  For more information see this
+  {{{https://github.com/apache/maven-surefire/tree/master/surefire-its/src/test/resources/junit5-testng}example}}.
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.testng</groupId>
+        <artifactId>testng</artifactId>
+        <version>7.1.0</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>com.github.testng-team</groupId>
+        <artifactId>testng-junit5</artifactId>
+        <version>0.0.1</version>
+        <scope>test</scope>
+        <exclusions>
+            <exclusion>
+                <groupId>org.junit.platform</groupId>
+                <artifactId>junit-platform-engine</artifactId>
+            </exclusion>
+        </exclusions>
+    </dependency>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
++---+
+
+  The Maven does not take any responsibility for broken compatibilities in this case and the responsibility for
+  the dependency <<<com.github.testng-team:testng-junit5>>>.
+
+** JUnit Runner
+
+  The JUnit4 library has the {{{https://junit.org/junit4/javadoc/latest/src-html/org/junit/runner/Runner.html}Runner}}
+  implemented in the JUnit5's artifact <<<junit-platform-runner>>>.
+
+  For more information see this
+  {{{https://github.com/apache/maven-surefire/tree/master/surefire-its/src/test/resources/junit5-runner}example}}.
+
++---+
+<dependencies>
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-engine</artifactId>
+        <version>5.6.2</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-runner</artifactId>
+        <version>1.6.2</version>
+        <scope>test</scope>
+    </dependency>
+</dependencies>
++---+
+
 * Provider Selection
 
    If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:
diff --git a/pom.xml b/pom.xml
index 2665b37..b24b0e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -355,7 +355,7 @@
       <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-core</artifactId>
-        <version>2.27.0</version>
+        <version>2.28.2</version>
         <exclusions>
           <exclusion>
             <groupId>org.hamcrest</groupId>
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1787JUnit5IT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1787JUnit5IT.java
new file mode 100644
index 0000000..0a493f5
--- /dev/null
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1787JUnit5IT.java
@@ -0,0 +1,122 @@
+package org.apache.maven.surefire.its.jiras;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaVersion;
+
+/**
+ *
+ */
+@SuppressWarnings( "checkstyle:magicnumber" )
+public class Surefire1787JUnit5IT extends SurefireJUnit4IntegrationTestCase
+{
+    @Before
+    public void javaVersion()
+    {
+        assumeJavaVersion( 1.8d );
+    }
+
+    @Test
+    public void bothEngines()
+    {
+        unpack( "junit-4-5" )
+            .activateProfile( "both-engines" )
+            .executeTest()
+            .verifyErrorFree( 2 )
+            .verifyTextInLog( "Running pkg.JUnit4Test" )
+            .verifyTextInLog( "Running pkg.JUnit5Test" );
+    }
+
+    @Test
+    public void apiAndEngine()
+    {
+        unpack( "junit-4-5" )
+            .activateProfile( "api-and-engines" )
+            .executeTest()
+            .verifyErrorFree( 2 )
+            .verifyTextInLog( "Running pkg.JUnit4Test" )
+            .verifyTextInLog( "Running pkg.JUnit5Test" );
+    }
+
+    @Test
+    public void bothApis()
+    {
+        unpack( "junit-4-5" )
+            .activateProfile( "both-api" )
+            .executeTest()
+            .verifyErrorFree( 2 )
+            .verifyTextInLog( "Running pkg.JUnit4Test" )
+            .verifyTextInLog( "Running pkg.JUnit5Test" );
+    }
+
+    @Test
+    public void selectJUnit4()
+    {
+        unpack( "junit-4-5" )
+            .activateProfile( "select-junit4" )
+            .executeTest()
+            .verifyErrorFree( 1 )
+            .verifyTextInLog( "Running pkg.JUnit4Test" );
+    }
+
+    @Test
+    public void selectJUnit5()
+    {
+        unpack( "junit-4-5" )
+            .activateProfile( "select-junit5" )
+            .executeTest()
+            .verifyErrorFree( 1 )
+            .verifyTextInLog( "Running pkg.JUnit5Test" );
+    }
+
+    @Test
+    public void testNgWithJupiterApi()
+    {
+        unpack( "junit5-testng" )
+            .activateProfile( "junit5-api" )
+            .executeTest()
+            .verifyErrorFree( 2 )
+            .verifyTextInLog( "Running pkg.JUnit5Test" )
+            .verifyTextInLog( "Running pkg.TestNGTest" );
+    }
+
+    @Test
+    public void testNgWithJupiterEngine()
+    {
+        unpack( "junit5-testng" )
+            .activateProfile( "junit5-engine" )
+            .executeTest()
+            .verifyErrorFree( 2 )
+            .verifyTextInLog( "Running pkg.JUnit5Test" )
+            .verifyTextInLog( "Running pkg.TestNGTest" );
+    }
+
+    @Test
+    public void junit4Runner()
+    {
+        unpack( "junit5-runner" )
+            .executeTest()
+            .verifyErrorFreeLog();
+    }
+}
diff --git a/surefire-its/src/test/resources/junit-4-5/pom.xml b/surefire-its/src/test/resources/junit-4-5/pom.xml
new file mode 100644
index 0000000..5f6a5a4
--- /dev/null
+++ b/surefire-its/src/test/resources/junit-4-5/pom.xml
@@ -0,0 +1,166 @@
+<?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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>junit-4-5</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>${java.specification.version}</maven.compiler.source>
+        <maven.compiler.target>${java.specification.version}</maven.compiler.target>
+    </properties>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${surefire.version}</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>both-engines</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-engine</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>api-and-engines</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>both-api</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                    <version>4.13</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>select-junit4</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                    <version>4.13</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.junit.vintage</groupId>
+                                <artifactId>junit-vintage-engine</artifactId>
+                                <version>5.6.2</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>select-junit5</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                    <version>4.13</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.junit.jupiter</groupId>
+                                <artifactId>junit-jupiter-engine</artifactId>
+                                <version>5.6.2</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit4Test.java b/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit4Test.java
new file mode 100644
index 0000000..04c7f99
--- /dev/null
+++ b/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit4Test.java
@@ -0,0 +1,10 @@
+package pkg;
+
+import org.junit.Test;
+
+public class JUnit4Test {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit5Test.java b/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit5Test.java
new file mode 100644
index 0000000..916eeab
--- /dev/null
+++ b/surefire-its/src/test/resources/junit-4-5/src/test/java/pkg/JUnit5Test.java
@@ -0,0 +1,10 @@
+package pkg;
+
+import org.junit.jupiter.api.Test;
+
+class JUnit5Test {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit5-runner/pom.xml b/surefire-its/src/test/resources/junit5-runner/pom.xml
new file mode 100644
index 0000000..c667e03
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-runner/pom.xml
@@ -0,0 +1,66 @@
+<?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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>junit5-runner</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>${java.specification.version}</maven.compiler.source>
+        <maven.compiler.target>${java.specification.version}</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>5.6.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-runner</artifactId>
+            <version>1.6.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${surefire.version}</version>
+                    <configuration>
+                        <test>JUnit5Tests</test>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+</project>
diff --git a/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/RootTest.java b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/RootTest.java
new file mode 100644
index 0000000..74928ec
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/RootTest.java
@@ -0,0 +1,10 @@
+package examples;
+
+import org.junit.Test;
+
+class RootTest {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/a/ATest.java b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/a/ATest.java
new file mode 100644
index 0000000..620f932
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/a/ATest.java
@@ -0,0 +1,10 @@
+package examples.a;
+
+import org.junit.Test;
+
+public class ATest {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/b/BTest.java b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/b/BTest.java
new file mode 100644
index 0000000..3a36713
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-runner/src/test/java/examples/b/BTest.java
@@ -0,0 +1,10 @@
+package examples.b;
+
+import org.junit.Test;
+
+public class BTest {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit5-runner/src/test/java/pkg/JUnit5Tests.java b/surefire-its/src/test/resources/junit5-runner/src/test/java/pkg/JUnit5Tests.java
new file mode 100644
index 0000000..4f2788a
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-runner/src/test/java/pkg/JUnit5Tests.java
@@ -0,0 +1,15 @@
+package pkg;
+
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.platform.suite.api.ExcludeTags;
+import org.junit.platform.suite.api.IncludePackages;
+import org.junit.platform.suite.api.SelectPackages;
+import org.junit.runner.RunWith;
+
+@RunWith(JUnitPlatform.class)
+@SelectPackages("examples")
+@IncludePackages("examples.a")
+@ExcludeTags("PROD")
+public class JUnit5Tests {
+
+}
diff --git a/surefire-its/src/test/resources/junit5-testng/pom.xml b/surefire-its/src/test/resources/junit5-testng/pom.xml
new file mode 100644
index 0000000..c18e464
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-testng/pom.xml
@@ -0,0 +1,94 @@
+<?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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.example</groupId>
+    <artifactId>testng-junit5</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>${java.specification.version}</maven.compiler.source>
+        <maven.compiler.target>${java.specification.version}</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>7.1.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.testng-team</groupId>
+            <artifactId>testng-junit5</artifactId>
+            <version>0.0.1</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.platform</groupId>
+                    <artifactId>junit-platform-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${surefire.version}</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>junit5-engine</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-engine</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>junit5-api</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-api</artifactId>
+                    <version>5.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/JUnit5Test.java b/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/JUnit5Test.java
new file mode 100644
index 0000000..916eeab
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/JUnit5Test.java
@@ -0,0 +1,10 @@
+package pkg;
+
+import org.junit.jupiter.api.Test;
+
+class JUnit5Test {
+    @Test
+    public void test() {
+
+    }
+}
diff --git a/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/TestNGTest.java b/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/TestNGTest.java
new file mode 100644
index 0000000..5b2443d
--- /dev/null
+++ b/surefire-its/src/test/resources/junit5-testng/src/test/java/pkg/TestNGTest.java
@@ -0,0 +1,10 @@
+package pkg;
+
+import org.testng.annotations.Test;
+
+public class TestNGTest {
+    @Test
+    public void test() {
+
+    }
+}