Author: krosenvold Date: Wed Nov 9 17:04:57 2011 New Revision: 1199853 URL: http://svn.apache.org/viewvc?rev=1199853&view=rev Log: [SUREFIRE-329] Support JUnit @Category
Main patch by Todd Lipcon. Slight modifications supplied by nkeywal. Both original patch and modifications heavily modified by me. Test cases in JUnit48TestCategoriesIT Added: maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit48TestCategoriesIT.java - copied, changed from r1188905, maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/pom.xml - copied, changed from r1188905, maven/surefire/trunk/surefire-providers/pom.xml maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java (with props) maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java (with props) maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java (with props) maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java (with props) maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java (with props) maven/surefire/trunk/surefire-providers/common-junit48/ maven/surefire/trunk/surefire-providers/common-junit48/pom.xml - copied, changed from r1188905, maven/surefire/trunk/surefire-providers/pom.xml maven/surefire/trunk/surefire-providers/common-junit48/src/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java (with props) maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java (with props) maven/surefire/trunk/surefire-providers/common-junit48/src/test/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java (with props) maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml (with props) maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java (with props) Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit47-redirect-output/pom.xml maven/surefire/trunk/surefire-providers/pom.xml maven/surefire/trunk/surefire-providers/surefire-junit47/pom.xml maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java (original) +++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java Wed Nov 9 17:04:57 2011 @@ -256,14 +256,7 @@ public abstract class AbstractSurefireMo { getProperties().setProperty( "parallel", this.getParallel() ); } - if ( this.getExcludedGroups() != null ) - { - getProperties().setProperty( "excludegroups", this.getExcludedGroups() ); - } - if ( this.getGroups() != null ) - { - getProperties().setProperty( "groups", this.getGroups() ); - } + convertGroupParameters(); if ( this.getThreadCount() > 0 ) { @@ -281,6 +274,22 @@ public abstract class AbstractSurefireMo } + private void convertGroupParameters() + { + if ( getProperties() == null ) // May be predefined from plugin paramaters + { + setProperties( new Properties() ); + } + if ( this.getExcludedGroups() != null ) + { + getProperties().setProperty( "excludedgroups", this.getExcludedGroups() ); + } + if ( this.getGroups() != null ) + { + getProperties().setProperty( "groups", this.getGroups() ); + } + } + protected boolean isAnyConcurrencySelected() { return this.getParallel() != null && this.getParallel().trim().length() > 0; @@ -379,11 +388,8 @@ public abstract class AbstractSurefireMo providerProperties = new Properties(); } - ProviderConfiguration providerConfiguration1 = - new ProviderConfiguration( directoryScannerParameters, failIfNoTests, reporterConfiguration, testNg, - testSuiteDefinition, providerProperties, null ); - - return providerConfiguration1; + return new ProviderConfiguration( directoryScannerParameters, failIfNoTests, reporterConfiguration, testNg, + testSuiteDefinition, providerProperties, null ); } StartupConfiguration createStartupConfiguration( ForkConfiguration forkConfiguration, ProviderInfo provider, @@ -1123,7 +1129,7 @@ public abstract class AbstractSurefireMo getLog().warn( "useSystemClassloader setting has no effect when not forking" ); } } - + private RunOrder getRunOrderObject() { RunOrder runOrder = RunOrder.valueOf( getRunOrder() ); return runOrder == null ? RunOrder.FILESYSTEM : runOrder; @@ -1262,6 +1268,7 @@ public abstract class AbstractSurefireMo public void addProviderProperties() { convertJunitCoreParameters(); + convertGroupParameters(); } public Classpath getProviderClasspath() Modified: maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java (original) +++ maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/util/TestsToRun.java Wed Nov 9 17:04:57 2011 @@ -19,14 +19,13 @@ package org.apache.maven.surefire.util; * under the License. */ -import org.apache.maven.surefire.testset.TestSetFailedException; - import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import org.apache.maven.surefire.testset.TestSetFailedException; /** * Contains all the tests that have been found according to specified include/exclude @@ -84,4 +83,20 @@ public class TestsToRun { return locatedClasses.iterator(); } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + sb.append( "TestsToRun: [" ); + Iterator it = iterator(); + while ( it.hasNext() ) + { + Class clazz = (Class) it.next(); + sb.append( " " ).append( clazz.getName() ); + } + + sb.append( ']' ); + return sb.toString(); + } + } Copied: maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit48TestCategoriesIT.java (from r1188905, maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java) URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit48TestCategoriesIT.java?p2=maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit48TestCategoriesIT.java&p1=maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java&r1=1188905&r2=1199853&rev=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java (original) +++ maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit48TestCategoriesIT.java Wed Nov 9 17:04:57 2011 @@ -20,50 +20,44 @@ package org.apache.maven.surefire.its; /** - * Test project using JUnit4.4 -dep. junit-dep includes only junit.* classes, and depends explicitly on hamcrest-core + * Test project using "groups" support * - * @author <a href="mailto:dfabul...@apache.org">Dan Fabulich</a> + * @author <a href="mailto:t...@apache.org">Todd Lipcon</a> */ -public class JUnitDepIT +public class JUnit48TestCategoriesIT extends SurefireVerifierTestClass { - public JUnitDepIT() + public JUnit48TestCategoriesIT() { - super( "/junit44-dep" ); + super( "/junit48-categories" ); } - public void testJUnit44Dep() + public void testCategoriesAB() throws Exception { - debugLogging(); - addGoal( "-Djunit-dep.version=4.4" ); - executeTest(); - - verifyErrorFreeLog(); - assertTestSuiteResults( 1, 0, 0, 0 ); - verifyTextInLog( "surefire-junit4" ); // Ahem. Will match on the 4.7 provider too - } - public void testJUnit44DepWithSneaky381() - throws Exception - { - debugLogging(); - activateProfile("provided381"); - addGoal( "-Djunit-dep.version=4.4" ); executeTest(); verifyErrorFreeLog(); - assertTestSuiteResults( 1, 0, 0, 0 ); + assertTestSuiteResults( 2, 0, 0, 0 ); + verifyTextInLog("catA: 1"); + verifyTextInLog("catB: 1"); + verifyTextInLog("catC: 0"); + verifyTextInLog("catNone: 0"); } - public void testJUnit47Dep() + public void testCategoriesAC() throws Exception { - debugLogging(); - addGoal( "-Djunit-dep.version=4.7" ); + addGoal( "-Dgroups=junit4.CategoryA,junit4.CategoryC" ); executeTest(); verifyErrorFreeLog(); - assertTestSuiteResults( 1, 0, 0, 0 ); - verifyTextInLog( "surefire-junit47" ); + assertTestSuiteResults( 6, 0, 0, 0 ); + verifyTextInLog("catA: 1"); + verifyTextInLog("catB: 0"); + verifyTextInLog("catC: 1"); + verifyTextInLog("catNone: 0"); + verifyTextInLog("mA: 1"); + verifyTextInLog("mB: 1"); // This seems questionable !? The class is annotated with category C and method with B + verifyTextInLog("mC: 1"); + verifyTextInLog("CatNone: 1"); } - - } Modified: maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java (original) +++ maven/surefire/trunk/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnitDepIT.java Wed Nov 9 17:04:57 2011 @@ -43,11 +43,12 @@ public class JUnitDepIT assertTestSuiteResults( 1, 0, 0, 0 ); verifyTextInLog( "surefire-junit4" ); // Ahem. Will match on the 4.7 provider too } + public void testJUnit44DepWithSneaky381() throws Exception { debugLogging(); - activateProfile("provided381"); + activateProfile( "provided381" ); addGoal( "-Djunit-dep.version=4.4" ); executeTest(); verifyErrorFreeLog(); @@ -65,5 +66,14 @@ public class JUnitDepIT verifyTextInLog( "surefire-junit47" ); } - + public void testJUnit48Dep() + throws Exception + { + debugLogging(); + addGoal( "-Djunit-dep.version=4.8" ); + executeTest(); + verifyErrorFreeLog(); + assertTestSuiteResults( 1, 0, 0, 0 ); + verifyTextInLog( "surefire-junit47" ); + } } Modified: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit47-redirect-output/pom.xml URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit47-redirect-output/pom.xml?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit47-redirect-output/pom.xml (original) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit47-redirect-output/pom.xml Wed Nov 9 17:04:57 2011 @@ -33,7 +33,7 @@ <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> - <version>2.7.2</version> + <version>${surefire.version}</version> </dependency> </dependencies> <configuration> Copied: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/pom.xml (from r1188905, maven/surefire/trunk/surefire-providers/pom.xml) URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/pom.xml?p2=maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/pom.xml&p1=maven/surefire/trunk/surefire-providers/pom.xml&r1=1188905&r2=1199853&rev=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/pom.xml (original) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/pom.xml Wed Nov 9 17:04:57 2011 @@ -18,51 +18,57 @@ ~ 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"> +<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.surefire</groupId> - <artifactId>surefire</artifactId> - <version>2.11-SNAPSHOT</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>surefire-providers</artifactId> - <packaging>pom</packaging> - - <name>SureFire Providers</name> - - <modules> - <module>common-junit3</module> - <module>common-junit4</module> - <module>surefire-junit3</module> - <module>surefire-junit4</module> - <module>surefire-junit47</module> - <module>surefire-testng-utils</module> - <module>surefire-testng</module> - </modules> + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>junit4</artifactId> + <version>1.0-SNAPSHOT</version> + <name>Test for JUnit 4.8.1</name> + + + <properties> + <junitVersion>4.8.1</junitVersion> + <groups>junit4.CategoryA,junit4.CategoryB</groups> + </properties> <dependencies> <dependency> - <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire-api</artifactId> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junitVersion}</version> + <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.version}</version> + <configuration> + <groups>${groups}</groups> + </configuration> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire-shadefire</artifactId> - <version>${project.version}</version> + <artifactId>surefire-junit47</artifactId> + <version>${surefire.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> -</project> +</project> Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,54 @@ +package junit4; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + + +public class BasicTest +{ + static int catACount = 0; + static int catBCount = 0; + static int catCCount = 0; + static int catNoneCount = 0; + + @Test + @Category(CategoryA.class) + public void testInCategoryA() + { + System.out.println( "Ran testInCategoryA" ); + catACount++; + } + + @Test + @Category(CategoryB.class) + public void testInCategoryB() + { + System.out.println( "Ran testInCategoryB" ); + catBCount++; + } + + @Test + @Category(CategoryC.class) + public void testInCategoryC() + { + System.out.println( "Ran testInCategoryC" ); + catCCount++; + } + + @Test + public void testInNoCategory() + { + System.out.println( "Ran testInNoCategory" ); + catNoneCount++; + } + + @AfterClass + public static void oneTimeTearDown() + { + System.out.println("catA: " + catACount + "\n" + + "catB: " + catBCount + "\n" + + "catC: " + catCCount + "\n" + + "catNone: " + catNoneCount); + } +} Propchange: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/BasicTest.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,3 @@ +package junit4; + +interface CategoryA {} Propchange: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryA.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,3 @@ +package junit4; + +interface CategoryB {} Propchange: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryB.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,3 @@ +package junit4; + +interface CategoryC {} Propchange: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryC.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java (added) +++ maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,49 @@ +package junit4; +import org.junit.AfterClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + + +@Category(CategoryC.class) +public class CategoryCTest +{ + static int catACount = 0; + static int catBCount = 0; + static int catCCount = 0; + static int catNoneCount = 0; + + @Test + public void testInCategoryA() + { + catACount++; + } + + @Test + @Category(CategoryB.class) + public void testInCategoryB() + { + catBCount++; + } + + @Test + @Category(CategoryC.class) + public void testInCategoryC() + { + catCCount++; + } + + @Test + public void testInNoCategory() + { + catNoneCount++; + } + + @AfterClass + public static void oneTimeTearDown() + { + System.out.println("mA: " + catACount + "\n" + + "mB: " + catBCount + "\n" + + "mC: " + catCCount + "\n" + + "CatNone: " + catNoneCount); + } +} Propchange: maven/surefire/trunk/surefire-integration-tests/src/test/resources/junit48-categories/src/test/java/junit4/CategoryCTest.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: maven/surefire/trunk/surefire-providers/common-junit48/pom.xml (from r1188905, maven/surefire/trunk/surefire-providers/pom.xml) URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/common-junit48/pom.xml?p2=maven/surefire/trunk/surefire-providers/common-junit48/pom.xml&p1=maven/surefire/trunk/surefire-providers/pom.xml&r1=1188905&r2=1199853&rev=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/pom.xml (original) +++ maven/surefire/trunk/surefire-providers/common-junit48/pom.xml Wed Nov 9 17:04:57 2011 @@ -1,4 +1,3 @@ -<?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 @@ -23,46 +22,38 @@ <parent> <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire</artifactId> + <artifactId>surefire-providers</artifactId> <version>2.11-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> - <artifactId>surefire-providers</artifactId> - <packaging>pom</packaging> + <artifactId>common-junit48</artifactId> - <name>SureFire Providers</name> - - <modules> - <module>common-junit3</module> - <module>common-junit4</module> - <module>surefire-junit3</module> - <module>surefire-junit4</module> - <module>surefire-junit47</module> - <module>surefire-testng-utils</module> - <module>surefire-testng</module> - </modules> + <name>Shared JUnit48 Provider Code</name> <dependencies> <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.8.1</version> + <scope>provided</scope> + </dependency> + <dependency> <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire-api</artifactId> + <artifactId>common-junit4</artifactId> + <version>${project.version}</version> </dependency> - </dependencies> + </dependencies> <build> <plugins> <plugin> - <artifactId>maven-surefire-plugin</artifactId> - <dependencies> - <dependency> - <groupId>org.apache.maven.surefire</groupId> - <artifactId>surefire-shadefire</artifactId> - <version>${project.version}</version> - </dependency> - </dependencies> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.5</source> + <target>1.5</target> + </configuration> </plugin> </plugins> </build> </project> - Added: maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java (added) +++ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,155 @@ +package org.apache.maven.surefire.common.junit48; + +/* + * 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.List; +import java.util.Properties; + +import org.junit.experimental.categories.Categories; +import org.junit.runner.Description; +import org.junit.runner.manipulation.Filter; + +/** + * @author Todd Lipcon + */ +public class FilterFactory +{ + private final ClassLoader testClassLoader; + + public FilterFactory( ClassLoader testClassLoader ) + { + this.testClassLoader = testClassLoader; + } + + public Filter createGroupFilter( Properties providerProperties ) + { + providerProperties.list( System.err ); + String groups = providerProperties.getProperty( "groups" ); + String excludedGroups = providerProperties.getProperty( "excludedgroups" ); + List<Filter> included = commaSeparatedListToFilters( groups ); + List<Filter> excluded = commaSeparatedListToFilters( excludedGroups ); + return new CombinedCategoryFilter( included, excluded ); + } + + private List<Filter> commaSeparatedListToFilters( String str ) + { + List<Filter> included = new ArrayList<Filter>(); + if ( str != null ) + { + for ( String group : str.split( "," ) ) + { + group = group.trim(); + if ( group == null || group.length() == 0) + { + continue; + } + Class<?> categoryType = classloadCategory( group ); + included.add( Categories.CategoryFilter.include( categoryType ) ); + } + } + return included; + } + + private static class CombinedCategoryFilter + extends Filter + { + private final List<Filter> includedFilters; + + private final List<Filter> excludedFilters; + + public CombinedCategoryFilter( List<Filter> includedFilters, List<Filter> excludedFilters ) + { + this.includedFilters = includedFilters; + this.excludedFilters = excludedFilters; + } + + @Override + public boolean shouldRun( Description description ) + { + return ( includedFilters.isEmpty() || inOneOfFilters( includedFilters, description ) ) && ( + excludedFilters.isEmpty() || !inOneOfFilters( excludedFilters, description ) ); + } + + private boolean inOneOfFilters( List<Filter> filters, Description description ) + { + for ( Filter f : filters ) + { + if ( f.shouldRun( description ) ) + { + return true; + } + } + return false; + } + + @Override + public String describe() + { + StringBuilder sb = new StringBuilder(); + if ( !includedFilters.isEmpty() ) + { + sb.append( "(" ); + sb.append( joinFilters( includedFilters, " OR " ) ); + sb.append( ")" ); + if ( !excludedFilters.isEmpty() ) + { + sb.append( " AND " ); + } + } + if ( !excludedFilters.isEmpty() ) + { + sb.append( "NOT (" ); + sb.append( joinFilters( includedFilters, " OR " ) ); + sb.append( ")" ); + } + + return sb.toString(); + } + + private String joinFilters( List<Filter> filters, String sep ) + { + int i = 0; + StringBuilder sb = new StringBuilder(); + for ( Filter f : filters ) + { + if ( i++ > 0 ) + { + sb.append( sep ); + } + sb.append( f.describe() ); + } + return sb.toString(); + } + } + + private Class<?> classloadCategory( String category ) + { + try + { + return testClassLoader.loadClass( category ); + } + catch ( ClassNotFoundException e ) + { + throw new RuntimeException( "Unable to load category: " + category, e ); + } + } + +} Propchange: maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/FilterFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java (added) +++ maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,50 @@ +package org.apache.maven.surefire.common.junit48; + +/* + * 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.util.ReflectionUtils; + +/** + * @author Kristian Rosenvold + */ +public final class JUnit48Reflector +{ + private static final String CATEGORIES = "org.junit.experimental.categories.Categories"; + private static final String CATEGORY = "org.junit.experimental.categories.Category"; + + private final Class categories; + + private final Class category; + + public JUnit48Reflector( ClassLoader testClassLoader ) + { + categories = ReflectionUtils.tryLoadClass( testClassLoader, CATEGORIES ); + category = ReflectionUtils.tryLoadClass( testClassLoader, CATEGORY ); + } + + public boolean isJUnit48Available() + { + return categories != null; + } + + public boolean isCategoryAnnotationPresent(Class clazz){ + return category != null && clazz.getAnnotation( category ) != null; + } +} Propchange: maven/surefire/trunk/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit48Reflector.java ------------------------------------------------------------------------------ svn:eol-style = native Added: maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java (added) +++ maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,57 @@ +package org.apache.maven.surefire.common.junit48; + +/* + * 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 junit.framework.TestCase; +import org.junit.experimental.categories.Category; + +/** + * @author Kristian Rosenvold + */ +public class JUnit48ReflectorTest + extends TestCase +{ + public void testIsJUnit48Available() + throws Exception + { + JUnit48Reflector jUnit48Reflector = new JUnit48Reflector( this.getClass().getClassLoader() ); + assertTrue( jUnit48Reflector.isJUnit48Available() ); + } + + public void testCategoryAnnotation() + throws Exception + { + JUnit48Reflector jUnit48Reflector = new JUnit48Reflector( this.getClass().getClassLoader() ); + assertTrue( jUnit48Reflector.isCategoryAnnotationPresent(Test1.class) ); + assertFalse( jUnit48Reflector.isCategoryAnnotationPresent(Test2.class) ); + } + + interface Foo{ + + } + @Category(Foo.class) + private class Test1 { + + } + private class Test2 { + + } + +} Propchange: maven/surefire/trunk/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/JUnit48ReflectorTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: maven/surefire/trunk/surefire-providers/pom.xml URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/pom.xml?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/pom.xml (original) +++ maven/surefire/trunk/surefire-providers/pom.xml Wed Nov 9 17:04:57 2011 @@ -36,6 +36,7 @@ <modules> <module>common-junit3</module> <module>common-junit4</module> + <module>common-junit48</module> <module>surefire-junit3</module> <module>surefire-junit4</module> <module>surefire-junit47</module> Added: maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml (added) +++ maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml Wed Nov 9 17:04:57 2011 @@ -0,0 +1,8 @@ +<project default="copy-resources"> + <target name="init"/> + <target name="copy-resources" depends="init"> + <copy todir="target/classes/META-INF" filtering="false"> + <fileset dir="src/main/resources/META-INF" includes="" excludes="**/*.java"/> + </copy> + </target> +</project> \ No newline at end of file Propchange: maven/surefire/trunk/surefire-providers/surefire-junit47/maven-eclipse.xml ------------------------------------------------------------------------------ svn:eol-style = native Modified: maven/surefire/trunk/surefire-providers/surefire-junit47/pom.xml URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/pom.xml?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-junit47/pom.xml (original) +++ maven/surefire/trunk/surefire-providers/surefire-junit47/pom.xml Wed Nov 9 17:04:57 2011 @@ -53,6 +53,11 @@ <artifactId>common-junit4</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>common-junit48</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build> Modified: maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java Wed Nov 9 17:04:57 2011 @@ -19,12 +19,15 @@ package org.apache.maven.surefire.junitc * under the License. */ +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory; import org.apache.maven.surefire.common.junit4.JUnit4TestChecker; +import org.apache.maven.surefire.common.junit48.FilterFactory; +import org.apache.maven.surefire.common.junit48.JUnit48Reflector; import org.apache.maven.surefire.providerapi.AbstractProvider; import org.apache.maven.surefire.providerapi.ProviderParameters; import org.apache.maven.surefire.report.ConsoleLogger; @@ -39,6 +42,9 @@ import org.apache.maven.surefire.util.Di import org.apache.maven.surefire.util.ScannerFilter; import org.apache.maven.surefire.util.TestsToRun; +import org.junit.runner.Description; +import org.junit.runner.manipulation.Filter; + /** * @author Kristian Rosenvold */ @@ -60,6 +66,7 @@ public class JUnitCoreProvider private TestsToRun testsToRun; + private JUnit48Reflector jUnit48Reflector; public JUnitCoreProvider( ProviderParameters providerParameters ) { @@ -70,7 +77,7 @@ public class JUnitCoreProvider this.scannerFilter = new JUnit4TestChecker( testClassLoader ); customRunListeners = JUnit4RunListenerFactory. createCustomListeners( providerParameters.getProviderProperties().getProperty( "listener" ) ); - + jUnit48Reflector = new JUnit48Reflector( testClassLoader ); } public Boolean isRunnable() @@ -93,9 +100,11 @@ public class JUnitCoreProvider final ConsoleLogger consoleLogger = providerParameters.getConsoleLogger(); consoleLogger.info( message ); + final Filter filter = jUnit48Reflector.isJUnit48Available() ? createJUnit48Filter() : null; + if ( testsToRun == null ) { - testsToRun = forkTestSet == null ? scanClassPath() : TestsToRun.fromClass( (Class) forkTestSet ); + testsToRun = forkTestSet == null ? getSuitesAsList( filter ) : TestsToRun.fromClass( (Class) forkTestSet ); } final Map<String, TestSet> testSetMap = new ConcurrentHashMap<String, TestSet>(); @@ -109,10 +118,34 @@ public class JUnitCoreProvider org.junit.runner.notification.RunListener jUnit4RunListener = new JUnitCoreRunListener( listener, testSetMap ); customRunListeners.add( 0, jUnit4RunListener ); - JUnitCoreWrapper.execute( testsToRun, jUnitCoreParameters, customRunListeners ); + JUnitCoreWrapper.execute( testsToRun, jUnitCoreParameters, customRunListeners, filter ); return reporterFactory.close(); } + @SuppressWarnings( "unchecked" ) + private TestsToRun getSuitesAsList( Filter filter ) + { + List<Class<?>> res = new ArrayList<Class<?>>( 500 ); + TestsToRun max = scanClassPath(); + Iterator<Class<?>> it = max.iterator(); + while ( it.hasNext() ) + { + Class<?> clazz = it.next(); + boolean isCategoryAnnotatedClass = jUnit48Reflector.isCategoryAnnotationPresent( clazz); + Description d = Description.createSuiteDescription( clazz ); + if ( !isCategoryAnnotatedClass || filter == null || filter.shouldRun( d ) ) + { + res.add( clazz ); + } + } + return new TestsToRun( res ); + } + + private Filter createJUnit48Filter() + { + return new FilterFactory( testClassLoader ).createGroupFilter( providerParameters.getProviderProperties() ); + } + private TestsToRun scanClassPath() { return directoryScanner.locateTestClasses( testClassLoader, scannerFilter ); Modified: maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java?rev=1199853&r1=1199852&r2=1199853&view=diff ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java (original) +++ maven/surefire/trunk/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java Wed Nov 9 17:04:57 2011 @@ -26,7 +26,9 @@ import org.apache.maven.surefire.util.Te import org.junit.runner.Computer; import org.junit.runner.JUnitCore; +import org.junit.runner.Request; import org.junit.runner.Result; +import org.junit.runner.manipulation.Filter; import org.junit.runner.notification.RunListener; /** @@ -38,7 +40,7 @@ import org.junit.runner.notification.Run class JUnitCoreWrapper { public static void execute( TestsToRun testsToRun, JUnitCoreParameters jUnitCoreParameters, - List<RunListener> listeners ) + List<RunListener> listeners, Filter filter ) throws TestSetFailedException { Computer computer = getComputer( jUnitCoreParameters ); @@ -47,9 +49,16 @@ class JUnitCoreWrapper { junitCore.addListener( runListener ); } + + Request req = Request.classes( computer, testsToRun.getLocatedClasses() ); + if ( filter != null ) + { + req = req.filterWith( filter ); + } + try { - final Result run = junitCore.run( computer, testsToRun.getLocatedClasses() ); + final Result run = junitCore.run( req ); if ( run.getFailureCount() > 0 ) { Added: maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java?rev=1199853&view=auto ============================================================================== --- maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java (added) +++ maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java Wed Nov 9 17:04:57 2011 @@ -0,0 +1,181 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2009, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * Licensed 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. + */ +package org.apache.maven.surefire.junitcore; + +import java.io.File; +import java.util.HashMap; +import org.apache.maven.plugin.surefire.report.FileReporterFactory; +import org.apache.maven.surefire.booter.StartupReportConfiguration; +import org.apache.maven.surefire.report.DefaultConsoleReporter; +import org.apache.maven.surefire.report.ReporterConfiguration; +import org.apache.maven.surefire.report.ReporterFactory; +import org.apache.maven.surefire.report.RunListener; + +import junit.framework.Assert; +import junit.framework.TestCase; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.Computer; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +/** + * TestCase that expose "No tests were executed!" on Test failure using Maven Surefire 2.6-SNAPSHOT + * and the JUnit 4.8 Runner. + * <p/> + * ------------------------------------------------------- + * T E S T S + * ------------------------------------------------------- + * <p/> + * Results : + * <p/> + * Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 + * <p/> + * [INFO] ------------------------------------------------------------------------ + * [INFO] BUILD FAILURE + * [INFO] ------------------------------------------------------------------------ + * [INFO] Total time: 11.011s + * [INFO] Finished at: Thu Jul 15 13:59:14 CEST 2010 + * [INFO] Final Memory: 24M/355M + * [INFO] ------------------------------------------------------------------------ + * [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test + * (default-test) on project xxxxxx: No tests were executed! (Set -DfailIfNoTests=false to + * ignore this error.) -> [Help 1] + * <p/> + * <p/> + * <dependency> + * <groupId>junit</groupId> + * <artifactId>junit</artifactId> + * <version>4.8.1</version> + * <scope>test</scope> + * </dependency> + * <p/> + * <dependency> + * <groupId>org.apache.maven.surefire</groupId> + * <artifactId>surefire-booter</artifactId> + * <version>2.6-SNAPSHOT</version> + * <scope>test</scope> + * </dependency> + * <dependency> + * <groupId>org.apache.maven.plugins</groupId> + * <artifactId>maven-surefire-plugin</artifactId> + * <version>2.6-SNAPSHOT</version> + * <scope>test</scope> + * </dependency> + * <dependency> + * <groupId>org.apache.maven.surefire</groupId> + * <artifactId>surefire-junit48</artifactId> + * <version>2.6-SNAPSHOT</version> + * <scope>test</scope> + * </dependency> + * + * @author <a href="mailto:as...@redhat.com">Aslak Knutsen</a> + * @version $Revision: $ + */ +public class MavenSurefireJUnit48RunnerTest + extends TestCase +{ + + /* + * Assumption: + * The ConcurrentReportingRunListener assumes a Test will be Started before it Fails or Finishes. + * + * Reality: + * JUnits ParentRunner is responsible for adding the BeforeClass/AfterClass statements to the + * statement execution chain. After BeforeClass is executed, a Statement that delegates to the + * abstract method: runChild(T child, RunNotifier notifier) is called. As the JavaDoc explains: + * "Subclasses are responsible for making sure that relevant test events are reported through {@code notifier}". + * When a @BeforeClass fail, the child that should handle the relevant test events(Started, Failed, Finished) + * is never executed. + * + * Result: + * When Test Failed event is received in ConcurrentReportingRunListener without a Started event received first, + * it causes a NullPointException because there is no ClassReporter setup for that class yet. When this Exception + * is thrown from the ConcurrentReportingRunListener, JUnit catches the exception and reports is as a Failed test. + * But to avoid a wild loop, it removes the failing Listener before calling Failed test again. Since the + * ConcurrentReportingRunListener now is removed from the chain it will never receive the RunFinished event + * and the recorded state will never be replayed on the ReportManager. + * + * The End result: ReporterManager falsely believe no Test were run. + * + */ + @SuppressWarnings( { "unchecked", "ThrowableResultOfMethodCallIgnored" } ) + public void testSurefireShouldBeAbleToReportRunStatusEvenWithFailingTests() + throws Exception + { + ReporterFactory reporterManagerFactory = new FileReporterFactory( StartupReportConfiguration.defaultNoXml() ); + + final HashMap<String, TestSet> classMethodCounts = new HashMap<String, TestSet>(); + RunListener reporter = + ConcurrentReporterManager.createInstance( classMethodCounts, reporterManagerFactory, false, false, + new DefaultConsoleReporter( System.out ) ); + + org.junit.runner.notification.RunListener concurrentReportingRunListener = + new JUnitCoreRunListener( reporter, classMethodCounts ); + Computer computer = new Computer(); + + JUnitCore junitCore = new JUnitCore(); + + junitCore.addListener( concurrentReportingRunListener ); + + Result result = junitCore.run( computer, FailingTestClassTestNot.class ); + + junitCore.removeListener( concurrentReportingRunListener ); + + Assert.assertEquals( "JUnit should report correctly number of test ran(Finished)", 0, result.getRunCount() ); + + // Sys.out swallowed in ConsoleReporter.. + for ( Failure failure : result.getFailures() ) + { + System.out.println( failure.getException().getMessage() ); + } + + Assert.assertEquals( "There should only be one Exception reported, the one from the failing TestCase", 1, + result.getFailureCount() ); + + Assert.assertEquals( "The exception thrown by the failing TestCase", RuntimeException.class, + result.getFailures().get( 0 ).getException().getClass() ); + + reporterManagerFactory.close(); + } + + private ReporterConfiguration getReporterConfiguration() + { + return new ReporterConfiguration( new File( "." ), true ); + } + + /** + * Simple TestCase to force a Exception in @BeforeClass. + */ + public static class FailingTestClassTestNot + { + @BeforeClass + public static void failingBeforeClass() + throws Exception + { + throw new RuntimeException( "Opps, we failed in @BeforeClass" ); + } + + @Test + public void shouldNeverBeCalled() + throws Exception + { + Assert.assertTrue( true ); + } + } +} Propchange: maven/surefire/trunk/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MavenSurefireJUnit48RunnerTest.java ------------------------------------------------------------------------------ svn:eol-style = native