You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kr...@apache.org on 2013/05/03 18:51:52 UTC
git commit: SUREFIRE-569 Add support for scanning Dependencies for
TestClasses
Updated Branches:
refs/heads/master 33e110fc4 -> c808eec80
SUREFIRE-569 Add support for scanning Dependencies for TestClasses
Configure Surefire to scan any project Dependency for TestClasses
to include in the given test run.
TestClasses found as part of a Dependency are handled in the same
way as the testClassesDirectory found test classes. Includes,
Excludes and Test filters work the same.
Configuration example:
<dependency>
<groupId>org.a</groupId>
<artifactId>a</artifactId>
</dependency>
<configuration>
<dependenciesToScan>
<dependency>org.a:a</dependency>
</dependenciesToScan>
</configuration>
Patch applied with rename of 1 file.
Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/c808eec8
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/c808eec8
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/c808eec8
Branch: refs/heads/master
Commit: c808eec805509f14160454829df8f496499f0f4e
Parents: 33e110f
Author: Aslak Knutsen <as...@redhat.com>
Authored: Sat Jan 12 23:13:30 2013 +0100
Committer: Kristian Rosenvold <kr...@apache.org>
Committed: Fri May 3 18:40:20 2013 +0200
----------------------------------------------------------------------
.../plugin/surefire/AbstractSurefireMojo.java | 50 ++++-
.../surefire/SurefireExecutionParameters.java | 4 +
.../plugin/surefire/util/DependencyScanner.java | 172 +++++++++++++++
.../plugin/surefire/util/DirectoryScanner.java | 50 +----
.../maven/plugin/surefire/util/ScannerUtil.java | 72 ++++++
.../surefire/util/DependenciesScannerTest.java | 94 ++++++++
.../Surefire569RunTestFromDependencyJarsIT.java | 25 ++
.../module1/pom.xml | 50 +++++
.../surefire-569-RunTestFromDependencyJars/pom.xml | 29 +++
.../testjar/pom.xml | 46 ++++
.../testjar/src/test/java/org/test/TestA.java | 10 +
.../testjar/src/test/java/org/test/TestB.java | 10 +
12 files changed, 565 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
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 c767ea3..bcd5737 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
@@ -58,6 +58,7 @@ import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
+import org.apache.maven.plugin.surefire.util.DependencyScanner;
import org.apache.maven.plugin.surefire.util.DirectoryScanner;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
@@ -581,6 +582,15 @@ public abstract class AbstractSurefireMojo
protected String runOrder;
/**
+ * List of dependencies to scan for test classes to include in the test run. Each dependency string must follow the format
+ * <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>
+ *
+ * @since 2.14
+ */
+ @Parameter(property = "dependenciesToScan")
+ protected List<String> dependenciesToScan;
+
+ /**
*
*/
@Component
@@ -617,7 +627,7 @@ public abstract class AbstractSurefireMojo
if ( verifyParameters() && !hasExecutedBefore() )
{
- DefaultScanResult scan = scanDirectories();
+ DefaultScanResult scan = scanForTestClasses();
if ( !isValidSuiteXmlFileConfig() && scan.isEmpty() )
{
if ( getEffectiveFailIfNoTests() )
@@ -640,12 +650,37 @@ public abstract class AbstractSurefireMojo
toolchain = getToolchain();
}
+ private DefaultScanResult scanForTestClasses()
+ {
+ DefaultScanResult scan = scanDirectories();
+ DefaultScanResult scanDeps = scanDependencies();
+ if(!scanDeps.isEmpty())
+ {
+ List combined = new ArrayList();
+ combined.addAll(scan.getFiles());
+ combined.addAll(scanDeps.getFiles());
+ scan = new DefaultScanResult(combined);
+ }
+ return scan;
+ }
+
private DefaultScanResult scanDirectories()
{
return new DirectoryScanner( getTestClassesDirectory(), getIncludeList(), getExcludeList(),
getSpecificTests() ).scan();
}
+ private DefaultScanResult scanDependencies()
+ {
+ try {
+ return new DependencyScanner(
+ DependencyScanner.filter(project.getTestArtifacts(), getDependenciesToScan()),
+ getIncludeList(), getExcludeList(), getSpecificTests()).scan();
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
boolean verifyParameters()
throws MojoFailureException, MojoExecutionException
{
@@ -666,7 +701,7 @@ public abstract class AbstractSurefireMojo
}
}
- if ( !getTestClassesDirectory().exists() )
+ if ( !getTestClassesDirectory().exists() && getDependenciesToScan().size() == 0)
{
if ( Boolean.TRUE.equals( getFailIfNoTests() ) )
{
@@ -1617,6 +1652,7 @@ public abstract class AbstractSurefireMojo
checksum.add( getObjectFactory() );
checksum.add( getFailIfNoTests() );
checksum.add( getRunOrder() );
+ checksum.add( getDependenciesToScan() );
addPluginSpecificChecksumItems( checksum );
return checksum.getSha1();
@@ -2561,6 +2597,16 @@ public abstract class AbstractSurefireMojo
this.runOrder = runOrder;
}
+ public List<String> getDependenciesToScan()
+ {
+ return this.dependenciesToScan;
+ }
+
+ public void setDependenciesToScan(List<String> dependenciesToScan)
+ {
+ this.dependenciesToScan = dependenciesToScan;
+ }
+
public PluginDescriptor getPluginDescriptor()
{
return pluginDescriptor;
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
index 5b79bcf..06dbe92 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireExecutionParameters.java
@@ -124,4 +124,8 @@ public interface SurefireExecutionParameters
Boolean getFailIfNoSpecifiedTests();
void setFailIfNoSpecifiedTests( Boolean failIfNoSpecifiedTests );
+
+ List<String> getDependenciesToScan();
+
+ void setDependenciesToScan(List<String> dependenciesToScan);
}
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
new file mode 100644
index 0000000..cfdecff
--- /dev/null
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DependencyScanner.java
@@ -0,0 +1,172 @@
+package org.apache.maven.plugin.surefire.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.convertToJavaClassName;
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.processIncludesExcludes;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.shared.utils.io.MatchPatterns;
+import org.apache.maven.surefire.util.DefaultScanResult;
+
+/**
+ * Scans dependencies looking for tests.
+ *
+ * @author Aslak Knutsen
+ */
+public class DependencyScanner {
+
+ private final List<File> dependenciesToScan;
+
+ protected final List<String> includes;
+
+ protected final List<String> excludes;
+
+ protected final List<String> specificTests;
+
+ public DependencyScanner(List<File> dependenciesToScan, List<String> includes, List<String> excludes, List<String> specificTests)
+ {
+ this.dependenciesToScan = dependenciesToScan;
+ this.includes = includes;
+ this.excludes = excludes;
+ this.specificTests = specificTests;
+ }
+
+ public DefaultScanResult scan() throws MojoExecutionException
+ {
+ Matcher matcher = new Matcher(includes, excludes, specificTests);
+ List<String> found = new ArrayList<String>();
+ for(File artifact : dependenciesToScan)
+ {
+ try
+ {
+ found.addAll(scanArtifact(artifact, matcher));
+ }
+ catch (IOException e)
+ {
+ throw new MojoExecutionException("Could not scan dependency " + artifact.toString(), e);
+ }
+ }
+ return new DefaultScanResult(found);
+ }
+
+ private List<String> scanArtifact(File artifact, Matcher matcher) throws IOException
+ {
+ List<String> found = new ArrayList<String>();
+
+ if(artifact != null) {
+ if(artifact.isFile()) {
+ JarFile jar = null;
+ try {
+ jar = new JarFile(artifact);
+ Enumeration<JarEntry> entries = jar.entries();
+ while(entries.hasMoreElements())
+ {
+ JarEntry entry = entries.nextElement();
+ if(matcher.shouldInclude(entry.getName()))
+ {
+ found.add(convertToJavaClassName(entry.getName()));
+ }
+ }
+ }
+ finally
+ {
+ if(jar != null)
+ {
+ jar.close();
+ }
+ }
+ }
+ }
+ return found;
+ }
+
+ public static List<File> filter(List<Artifact> artifacts, List<String> groupArtifactIds)
+ {
+ List<File> matches = new ArrayList<File>();
+ if(groupArtifactIds == null || artifacts == null)
+ {
+ return matches;
+ }
+ for(Artifact artifact : artifacts)
+ {
+ for(String groups : groupArtifactIds)
+ {
+ String[] groupArtifact = groups.split(":");
+ if(groupArtifact.length != 2)
+ {
+ throw new IllegalArgumentException(
+ "dependencyToScan argument should be in format 'groupid:artifactid': " + groupArtifact);
+ }
+ if(
+ artifact.getGroupId().matches(groupArtifact[0]) &&
+ artifact.getArtifactId().matches(groupArtifact[1]))
+ {
+ matches.add(artifact.getFile());
+ }
+ }
+ }
+ return matches;
+ }
+
+ private class Matcher {
+
+ private MatchPatterns includes;
+ private MatchPatterns excludes;
+
+ private SpecificFileFilter specificTestFilter;
+
+ public Matcher(List<String> includes, List<String> excludes, List<String> specificTests)
+ {
+ String[] specific = specificTests == null ? new String[0] : processIncludesExcludes( specificTests );
+ specificTestFilter = new SpecificFileFilter( specific );
+
+ if(includes != null && includes.size() > 0)
+ {
+ this.includes = MatchPatterns.from(processIncludesExcludes(includes));
+ }
+ else
+ {
+ this.includes = MatchPatterns.from("**");
+ }
+ this.excludes = MatchPatterns.from(processIncludesExcludes(excludes));
+ }
+
+ public boolean shouldInclude(String name)
+ {
+ if(!name.endsWith(".class"))
+ {
+ return false;
+ }
+ boolean isIncluded = includes.matches(name, false);
+ boolean isExcluded = excludes.matches(name, false);
+
+ return isIncluded && !isExcluded && specificTestFilter.accept(name);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DirectoryScanner.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DirectoryScanner.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DirectoryScanner.java
index 45c2a5a..1d1f3dc 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DirectoryScanner.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/DirectoryScanner.java
@@ -18,12 +18,14 @@ package org.apache.maven.plugin.surefire.util;
* specific language governing permissions and limitations
* under the License.
*/
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.convertToJavaClassName;
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.processIncludesExcludes;
+import static org.apache.maven.plugin.surefire.util.ScannerUtil.stripBaseDir;
import java.io.File;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import org.apache.commons.lang3.StringUtils;
+
import org.apache.maven.surefire.util.DefaultScanResult;
/**
@@ -34,13 +36,6 @@ import org.apache.maven.surefire.util.DefaultScanResult;
*/
public class DirectoryScanner
{
-
- private static final String FS = System.getProperty( "file.separator" );
-
- private static final String JAVA_SOURCE_FILE_EXTENSION = ".java";
-
- private static final String JAVA_CLASS_FILE_EXTENSION = ".class";
-
private final File basedir;
private final List<String> includes;
@@ -91,39 +86,4 @@ public class DirectoryScanner
}
return new DefaultScanResult( result );
}
-
- private String convertToJavaClassName( String test )
- {
- return StringUtils.removeEnd( test, ".class" ).replace( FS, "." );
- }
-
- private String stripBaseDir( String basedir, String test )
- {
- return StringUtils.removeStart( test, basedir );
- }
-
- private static String[] processIncludesExcludes( List<String> list )
- {
- List<String> newList = new ArrayList<String>();
- for ( Object aList : list )
- {
- String include = (String) aList;
- String[] includes = include.split( "," );
- Collections.addAll( newList, includes );
- }
-
- String[] incs = new String[newList.size()];
-
- for ( int i = 0; i < incs.length; i++ )
- {
- String inc = newList.get( i );
- if ( inc.endsWith( JAVA_SOURCE_FILE_EXTENSION ) )
- {
- inc = StringUtils.removeEnd( inc, JAVA_SOURCE_FILE_EXTENSION ) + JAVA_CLASS_FILE_EXTENSION;
- }
- incs[i] = inc;
-
- }
- return incs;
- }
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
new file mode 100644
index 0000000..5ca9644
--- /dev/null
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/util/ScannerUtil.java
@@ -0,0 +1,72 @@
+package org.apache.maven.plugin.surefire.util;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+final class ScannerUtil {
+
+ private ScannerUtil() {}
+
+ private static final String FS = System.getProperty( "file.separator" );
+
+ private static final String JAVA_SOURCE_FILE_EXTENSION = ".java";
+
+ private static final String JAVA_CLASS_FILE_EXTENSION = ".class";
+
+ public static String convertToJavaClassName( String test )
+ {
+ return StringUtils.removeEnd( test, ".class" ).replace( FS, "." );
+ }
+
+ public static String stripBaseDir( String basedir, String test )
+ {
+ return StringUtils.removeStart( test, basedir );
+ }
+
+ public static String[] processIncludesExcludes( List<String> list )
+ {
+ List<String> newList = new ArrayList<String>();
+ for ( Object aList : list )
+ {
+ String include = (String) aList;
+ String[] includes = include.split( "," );
+ Collections.addAll( newList, includes );
+ }
+
+ String[] incs = new String[newList.size()];
+
+ for ( int i = 0; i < incs.length; i++ )
+ {
+ String inc = newList.get( i );
+ if ( inc.endsWith( JAVA_SOURCE_FILE_EXTENSION ) )
+ {
+ inc = StringUtils.removeEnd( inc, JAVA_SOURCE_FILE_EXTENSION ) + JAVA_CLASS_FILE_EXTENSION;
+ }
+ incs[i] = inc;
+
+ }
+ return incs;
+ }
+}
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
new file mode 100644
index 0000000..c897e1e
--- /dev/null
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/util/DependenciesScannerTest.java
@@ -0,0 +1,94 @@
+package org.apache.maven.plugin.surefire.util;
+
+/*
+ * 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 java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.apache.maven.surefire.util.ScanResult;
+
+/**
+ * @author Aslak Knutsen
+ */
+public class DependenciesScannerTest
+ extends TestCase
+{
+ public void testLocateTestClasses()
+ throws Exception
+ {
+ File testFile = writeTestFile();
+
+ // use target as people can configure ide to compile in an other place than maven
+ Artifact artifact = new DefaultArtifact(
+ "org.surefire.dependency", "test-jar",
+ VersionRange.createFromVersion("1.0"), "test", "jar", "tests", null);
+ artifact.setFile(testFile);
+
+ List<String> scanDependencies = new ArrayList<String>();
+ scanDependencies.add("org.surefire.dependency:test-jar");
+
+ List<String> include = new ArrayList<String>();
+ include.add( "**/*A.java" );
+ List<String> exclude = new ArrayList<String>();
+
+ DependencyScanner scanner = new DependencyScanner(
+ DependencyScanner.filter(Arrays.asList(artifact), scanDependencies),
+ include, exclude, new ArrayList<String>() );
+
+ ScanResult classNames = scanner.scan();
+ assertNotNull( classNames );
+ System.out.println( "classNames " + classNames.toString() );
+ assertEquals( 1, classNames.size() );
+ System.out.println(classNames.getClassName(0));
+
+ Properties props = new Properties();
+ classNames.writeTo( props );
+ assertEquals( 1, props.size() );
+ }
+
+ private File writeTestFile() throws Exception {
+ File output = new File("target/DependenciesScannerTest-tests.jar");
+ output.delete();
+
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(output));
+
+ out.putNextEntry(new ZipEntry("org/test/TestA.class"));
+ out.closeEntry();
+ out.putNextEntry(new ZipEntry("org/test/TestB.class"));
+ out.closeEntry();
+ out.close();
+ return output;
+ }
+}
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire569RunTestFromDependencyJarsIT.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire569RunTestFromDependencyJarsIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire569RunTestFromDependencyJarsIT.java
new file mode 100644
index 0000000..cb9c92d
--- /dev/null
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire569RunTestFromDependencyJarsIT.java
@@ -0,0 +1,25 @@
+package org.apache.maven.surefire.its.jiras;
+
+import org.apache.maven.surefire.its.fixture.OutputValidator;
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.junit.Test;
+
+/**
+ * SUREFIRE-569 Add support for scanning Dependencies for TestClasses
+ *
+ * @author Aslak Knutsen
+ */
+public class Surefire569RunTestFromDependencyJarsIT
+ extends SurefireJUnit4IntegrationTestCase {
+
+ @Test
+ public void shouldScanAndRunTestsInDependencyJars() throws Exception {
+ SurefireLauncher launcher = unpack( "surefire-569-RunTestFromDependencyJars" );
+ launcher.addGoal("test").addGoal("install");
+ launcher.executeCurrentGoals();
+
+ OutputValidator module1 = launcher.getSubProjectValidator("module1");
+ module1.assertTestSuiteResults(1, 0, 0, 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/module1/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/module1/pom.xml b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/module1/pom.xml
new file mode 100644
index 0000000..7f1c672
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/module1/pom.xml
@@ -0,0 +1,50 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.plugins.surefire</groupId>
+ <artifactId>surefire-569-RunTestFromDependencyJars</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+
+ <groupId>org.apache.maven.plugins.surefire.dependency-jar</groupId>
+ <artifactId>module1</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <type>jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.plugins.surefire.dependency-jar</groupId>
+ <artifactId>testjar</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*A*.java</include>
+ </includes>
+ <dependenciesToScan>
+ <dependency>org.apache.maven.plugins.surefire.dependency-jar:testjar</dependency>
+ </dependenciesToScan>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/pom.xml b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/pom.xml
new file mode 100644
index 0000000..cd55a0e
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/pom.xml
@@ -0,0 +1,29 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.plugins.surefire</groupId>
+ <artifactId>surefire-569-RunTestFromDependencyJars</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <surefire.version>2.14-SNAPSHOT</surefire.version>
+ </properties>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <modules>
+ <module>testjar</module>
+ <module>module1</module>
+ </modules>
+</project>
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/pom.xml b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/pom.xml
new file mode 100644
index 0000000..ddfe3c0
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/pom.xml
@@ -0,0 +1,46 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.plugins.surefire</groupId>
+ <artifactId>surefire-569-RunTestFromDependencyJars</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+
+ <groupId>org.apache.maven.plugins.surefire.dependency-jar</groupId>
+ <artifactId>testjar</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <type>jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestA.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestA.java b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestA.java
new file mode 100644
index 0000000..6f432d1
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestA.java
@@ -0,0 +1,10 @@
+package org.test;
+
+import org.junit.Test;
+
+public class TestA {
+
+ @Test
+ public void shouldRun() {
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c808eec8/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestB.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestB.java b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestB.java
new file mode 100644
index 0000000..7e91ddd
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-569-RunTestFromDependencyJars/testjar/src/test/java/org/test/TestB.java
@@ -0,0 +1,10 @@
+package org.test;
+
+import org.junit.Test;
+
+public class TestB {
+
+ @Test
+ public void shouldRun() {
+ }
+}
\ No newline at end of file