This is an automated email from the ASF dual-hosted git repository. tibordigana pushed a commit to branch junit5-displayname in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit ff871c85dab97cd382190b89a123664c178d1697 Author: tibordigana <[email protected]> AuthorDate: Sat Jan 5 15:48:30 2019 +0100 junit5-displayname --- .../plugin/surefire/report/WrappedReportEntry.java | 9 +- .../surefire/runorder/StatisticsReporter.java | 5 +- .../surefire/report/WrappedReportEntryTest.java | 14 +- .../runorder/RunEntryStatisticsMapTest.java | 128 ++++++++- pom.xml | 4 +- .../surefire/runorder/RunEntryStatistics.java | 47 +--- .../surefire/runorder/RunEntryStatisticsMap.java | 172 ++++++++----- .../apache/maven/surefire/report/ReportEntry.java | 8 + .../maven/surefire/report/SimpleReportEntry.java | 6 + .../maven/surefire/util/internal}/ClassMethod.java | 32 ++- .../util/internal/TestClassMethodNameUtils.java | 32 ++- .../runorder/ThreadedExecutionSchedulerTest.java | 26 +- surefire-its/pom.xml | 2 +- .../maven/surefire/its/JUnitPlatformEnginesIT.java | 8 +- .../surefire/report/PojoStackTraceWriter.java | 24 ++ .../surefire/common/junit4/JUnit4ProviderUtil.java | 38 +-- .../surefire/common/junit4/JUnit4RunListener.java | 48 +--- .../common/junit4/JUnit4StackTraceWriter.java | 23 +- .../maven/surefire/common/junit4/Notifier.java | 4 +- .../common/junit4/JUnit4ProviderUtilTest.java | 15 +- .../common/junit48/JUnit46StackTraceWriter.java | 60 ----- surefire-providers/surefire-junit-platform/pom.xml | 4 + .../surefire/junitplatform/RunListenerAdapter.java | 286 +++++++++------------ .../surefire/junitplatform/JUnit47SuiteTest.java} | 45 ++-- .../junitplatform/JUnitPlatformProviderTest.java | 8 +- .../junitplatform/RunListenerAdapterTest.java | 124 +++++---- .../maven/surefire/junit/JUnitTestSetTest.java | 8 +- .../maven/surefire/junit4/TestResolverFilter.java | 2 +- .../surefire/junitcore/JUnitCoreRunListener.java | 20 +- .../junitcore/NonConcurrentRunListener.java | 21 +- .../junitcore/JUnitCoreRunListenerTest.java | 2 - .../maven/surefire/testng/TestNGReporter.java | 32 +-- .../surefire/report/SurefireReportParser.java | 29 +-- .../surefire/report/SurefireReportParserTest.java | 42 +-- 34 files changed, 677 insertions(+), 651 deletions(-) diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java index 3426e3a..ba11bbc 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java @@ -74,6 +74,12 @@ public class WrappedReportEntry return elapsed; } + @Override + public int getElapsed( int fallback ) + { + return elapsed == null ? fallback : elapsed; + } + public ReportEntryType getReportEntryType() { return reportEntryType; @@ -137,8 +143,7 @@ public class WrappedReportEntry public String getReportName() { - final int i = getName().lastIndexOf( "(" ); - return i > 0 ? getName().substring( 0, i ) : getName(); + return getName(); } public String getReportName( String suffix ) diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/runorder/StatisticsReporter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/runorder/StatisticsReporter.java index a53db02..2d9a175 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/runorder/StatisticsReporter.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/runorder/StatisticsReporter.java @@ -20,7 +20,8 @@ package org.apache.maven.plugin.surefire.runorder; */ import java.io.File; -import java.io.FileNotFoundException; +import java.io.IOException; + import org.apache.maven.surefire.report.ReportEntry; import static org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMap.fromFile; @@ -54,7 +55,7 @@ public class StatisticsReporter { newResults.serialize( dataFile ); } - catch ( FileNotFoundException e ) + catch ( IOException e ) { throw new RuntimeException( e ); } diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java index 030fc2f..f499ec3 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java @@ -29,9 +29,7 @@ import junit.framework.TestCase; public class WrappedReportEntryTest extends TestCase { - public void testClassNameOnly() - throws Exception { String category = "surefire.testcase.JunitParamsTest"; WrappedReportEntry wr = @@ -42,16 +40,15 @@ public class WrappedReportEntryTest public void testRegular() { - ReportEntry reportEntry = new SimpleReportEntry( "fud", "testSum(surefire.testcase.NonJunitParamsTest)" ); + ReportEntry reportEntry = new SimpleReportEntry( "fud", "testSum" ); WrappedReportEntry wr = new WrappedReportEntry( reportEntry, null, 12, null, null ); final String reportName = wr.getReportName(); assertEquals( "testSum", reportName ); } public void testGetReportNameWithParams() - throws Exception { - String category = "[0] 1\u002C 2\u002C 3 (testSum)(surefire.testcase.JunitParamsTest)"; + String category = "[0] 1\u002C 2\u002C 3 (testSum)"; ReportEntry reportEntry = new SimpleReportEntry( "fud", category ); WrappedReportEntry wr = new WrappedReportEntry( reportEntry, null, 12, null, null ); final String reportName = wr.getReportName(); @@ -59,15 +56,12 @@ public class WrappedReportEntryTest } public void testElapsed() - throws Exception { - String category = "[0] 1\u002C 2\u002C 3 (testSum)(surefire.testcase.JunitParamsTest)"; + String category = "[0] 1\u002C 2\u002C 3 (testSum)"; ReportEntry reportEntry = new SimpleReportEntry( "fud", category ); WrappedReportEntry wr = new WrappedReportEntry( reportEntry, null, 12, null, null ); String elapsedTimeSummary = wr.getElapsedTimeSummary(); - assertEquals( "[0] 1, 2, 3 (testSum)(surefire.testcase.JunitParamsTest) Time elapsed: 0.012 s", + assertEquals( "[0] 1, 2, 3 (testSum) Time elapsed: 0.012 s", elapsedTimeSummary ); } - - } diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java index 5a171ab..42698d7 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java @@ -20,15 +20,23 @@ package org.apache.maven.plugin.surefire.runorder; */ import java.io.File; +import java.io.FileInputStream; import java.io.IOException; -import java.io.StringReader; +import java.io.InputStream; +import java.io.StringBufferInputStream; import java.util.Arrays; import java.util.List; + import org.apache.maven.surefire.report.ReportEntry; import org.apache.maven.surefire.report.SimpleReportEntry; import junit.framework.TestCase; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.io.IOUtils.readLines; +import static org.apache.maven.surefire.util.internal.StringUtils.NL; +import static org.fest.assertions.Assertions.assertThat; + /** * @author Kristian Rosenvold */ @@ -36,9 +44,8 @@ public class RunEntryStatisticsMapTest extends TestCase { public void testPrioritizedClassRuntime() - throws IOException { - final RunEntryStatisticsMap runEntryStatisticsMap = RunEntryStatisticsMap.fromReader( getStatisticsFile() ); + final RunEntryStatisticsMap runEntryStatisticsMap = RunEntryStatisticsMap.fromStream( getStatisticsFile() ); final List<Class<?>> list = Arrays.<Class<?>>asList( A.class, B.class, C.class ); final List<Class<?>> prioritizedTestsClassRunTime = runEntryStatisticsMap.getPrioritizedTestsClassRunTime( list, 2 ); @@ -48,9 +55,8 @@ public class RunEntryStatisticsMapTest } public void testPrioritizedFailureFirst() - throws IOException { - final RunEntryStatisticsMap runEntryStatisticsMap = RunEntryStatisticsMap.fromReader( getStatisticsFile() ); + final RunEntryStatisticsMap runEntryStatisticsMap = RunEntryStatisticsMap.fromStream( getStatisticsFile() ); final List<Class<?>> list = Arrays.<Class<?>>asList( A.class, B.class, NewClass.class, C.class ); final List<Class<?>> prioritizedTestsClassRunTime = runEntryStatisticsMap.getPrioritizedTestsByFailureFirst( list ); @@ -60,12 +66,12 @@ public class RunEntryStatisticsMapTest assertEquals( B.class, prioritizedTestsClassRunTime.get( 3 ) ); } - private StringReader getStatisticsFile() + private InputStream getStatisticsFile() { - String content = "0,17,testA(org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$A)\n" + - "2,42,testB(org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$B)\n" + - "1,100,testC(org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$C)\n"; - return new StringReader( content ); + String content = "0,17,org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$A,testA\n" + + "2,42,org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$B,testB\n" + + "1,100,org.apache.maven.plugin.surefire.runorder.RunEntryStatisticsMapTest$C,testC\n"; + return new StringBufferInputStream( content ); } public void testSerialize() @@ -84,15 +90,111 @@ public class RunEntryStatisticsMapTest newResults.add( existingEntries.createNextGeneration( reportEntry3 ) ); newResults.serialize( data ); + try ( InputStream io = new FileInputStream( data) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "1,17,abc,willFail", "1,42,abc,method1", "1,100,abc,method3" ); + } RunEntryStatisticsMap nextRun = RunEntryStatisticsMap.fromFile( data ); newResults = new RunEntryStatisticsMap(); - newResults.add( existingEntries.createNextGeneration( reportEntry1 ) ); - newResults.add( existingEntries.createNextGenerationFailure( reportEntry2 ) ); - newResults.add( existingEntries.createNextGeneration( reportEntry3 ) ); + ReportEntry newRunReportEntry1 = new SimpleReportEntry( "abc", "method1", 52 ); + ReportEntry newRunReportEntry2 = new SimpleReportEntry( "abc", "willFail", 27 ); + ReportEntry newRunReportEntry3 = new SimpleReportEntry( "abc", "method3", 110 ); + + newResults.add( nextRun.createNextGeneration( newRunReportEntry1 ) ); + newResults.add( nextRun.createNextGenerationFailure( newRunReportEntry2 ) ); + newResults.add( nextRun.createNextGeneration( newRunReportEntry3 ) ); newResults.serialize( data ); + try ( InputStream io = new FileInputStream( data ) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "0,27,abc,willFail", "2,52,abc,method1", "2,110,abc,method3" ); + } + } + + public void testMultiLineTestMethodName() throws IOException + { + File data = File.createTempFile( "surefire-unit", "test" ); + RunEntryStatisticsMap reportEntries = RunEntryStatisticsMap.fromFile( data ); + ReportEntry reportEntry = new SimpleReportEntry( "abc", "line1\nline2" + NL + " line3", 42 ); + reportEntries.add( reportEntries.createNextGeneration( reportEntry ) ); + + reportEntries.serialize( data ); + try ( InputStream io = new FileInputStream( data ) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "1,42,abc,line1", " line2", " line3" ); + } + + RunEntryStatisticsMap nextRun = RunEntryStatisticsMap.fromFile( data ); + assertThat( data.delete() ).isTrue(); + nextRun.serialize( data ); + try ( InputStream io = new FileInputStream( data ) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "1,42,abc,line1", " line2", " line3" ); + } + } + + public void testCombinedMethodNames() throws IOException + { + File data = File.createTempFile( "surefire-unit", "test" ); + RunEntryStatisticsMap reportEntries = RunEntryStatisticsMap.fromFile( data ); + reportEntries.add( reportEntries.createNextGeneration( new SimpleReportEntry( "abc", "line1\nline2", 42 ) ) ); + reportEntries.add( reportEntries.createNextGeneration( new SimpleReportEntry( "abc", "test", 10 ) ) ); + + reportEntries.serialize( data ); + try ( InputStream io = new FileInputStream( data ) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "1,10,abc,test", + "1,42,abc,line1", + " line2" ); + } + + RunEntryStatisticsMap nextRun = RunEntryStatisticsMap.fromFile( data ); + assertThat( data.delete() ).isTrue(); + nextRun.serialize( data ); + try ( InputStream io = new FileInputStream( data ) ) + { + List<String> lines = readLines( io, UTF_8 ); + + assertThat( lines ) + .hasSize( 3 ); + + assertThat( lines ) + .containsSequence( "1,10,abc,test", + "1,42,abc,line1", + " line2" ); + } } class A diff --git a/pom.xml b/pom.xml index 72b9b5a..a048c46 100644 --- a/pom.xml +++ b/pom.xml @@ -277,12 +277,12 @@ <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> - <version>1.3.1</version> + <version>1.3.2</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> - <version>5.3.1</version> + <version>5.3.2</version> </dependency> <dependency> <groupId>org.mockito</groupId> diff --git a/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatistics.java b/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatistics.java index 7c794dc..1ccc4ee 100644 --- a/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatistics.java +++ b/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatistics.java @@ -19,8 +19,7 @@ package org.apache.maven.plugin.surefire.runorder; * under the License. */ -import java.util.StringTokenizer; -import org.apache.maven.surefire.report.ReportEntry; +import org.apache.maven.surefire.util.internal.ClassMethod; /** * @author Kristian Rosenvold @@ -31,39 +30,33 @@ public class RunEntryStatistics private final int successfulBuilds; - private final String testName; + private final ClassMethod classMethod; - private RunEntryStatistics( int runTime, int successfulBuilds, String testName ) + RunEntryStatistics( int runTime, int successfulBuilds, String clazz, String method ) { - this.runTime = runTime; - this.successfulBuilds = successfulBuilds; - this.testName = testName; + this( runTime, successfulBuilds, new ClassMethod( clazz, method ) ); } - public static RunEntryStatistics fromReportEntry( ReportEntry previous ) + RunEntryStatistics( int runTime, int successfulBuilds, ClassMethod classMethod ) { - final Integer elapsed = previous.getElapsed(); - return new RunEntryStatistics( elapsed != null ? elapsed : 0, 0, previous.getName() ); + this.runTime = runTime; + this.successfulBuilds = successfulBuilds; + this.classMethod = classMethod; } - public static RunEntryStatistics fromValues( int runTime, int successfulBuilds, Class clazz, String testName ) + public ClassMethod getClassMethod() { - return new RunEntryStatistics( runTime, successfulBuilds, testName + "(" + clazz.getName() + ")" ); + return classMethod; } public RunEntryStatistics nextGeneration( int runTime ) { - return new RunEntryStatistics( runTime, this.successfulBuilds + 1, this.testName ); + return new RunEntryStatistics( runTime, successfulBuilds + 1, classMethod ); } public RunEntryStatistics nextGenerationFailure( int runTime ) { - return new RunEntryStatistics( runTime, 0, this.testName ); - } - - public String getTestName() - { - return testName; + return new RunEntryStatistics( runTime, 0, classMethod ); } public int getRunTime() @@ -75,20 +68,4 @@ public class RunEntryStatistics { return successfulBuilds; } - - public static RunEntryStatistics fromString( String line ) - { - StringTokenizer tok = new StringTokenizer( line, "," ); - int successfulBuilds = Integer.parseInt( tok.nextToken() ); - int runTime = Integer.parseInt( tok.nextToken() ); - String className = tok.nextToken(); - return new RunEntryStatistics( runTime, successfulBuilds, className ); - } - - @Override - public String toString() - { - return successfulBuilds + "," + runTime + "," + testName; - } - } diff --git a/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMap.java b/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMap.java index 1a685dc..09a4445 100644 --- a/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMap.java +++ b/surefire-api/src/main/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMap.java @@ -19,38 +19,41 @@ package org.apache.maven.plugin.surefire.runorder; * under the License. */ - import org.apache.maven.surefire.report.ReportEntry; +import org.apache.maven.surefire.util.internal.ClassMethod; -import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; -import java.io.FileNotFoundException; +import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.Scanner; +import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import static java.lang.Integer.parseInt; +import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Collections.sort; -import static org.apache.maven.plugin.surefire.runorder.RunEntryStatistics.fromReportEntry; -import static org.apache.maven.plugin.surefire.runorder.RunEntryStatistics.fromString; +import static org.apache.maven.surefire.util.internal.StringUtils.NL; /** * @author Kristian Rosenvold */ public final class RunEntryStatisticsMap { - private final Map<String, RunEntryStatistics> runEntryStatistics; + private final Map<ClassMethod, RunEntryStatistics> runEntryStatistics; - public RunEntryStatisticsMap( Map<String, RunEntryStatistics> runEntryStatistics ) + private RunEntryStatisticsMap( Map<ClassMethod, RunEntryStatistics> runEntryStatistics ) { this.runEntryStatistics = new ConcurrentHashMap<>( runEntryStatistics ); } @@ -66,7 +69,7 @@ public final class RunEntryStatisticsMap { try { - return fromReader( new FileReader( file ) ); + return fromStream( new FileInputStream( file ) ); } catch ( IOException e ) { @@ -79,62 +82,124 @@ public final class RunEntryStatisticsMap } } - static RunEntryStatisticsMap fromReader( Reader fileReader ) - throws IOException + static RunEntryStatisticsMap fromStream( InputStream fileReader ) { - Map<String, RunEntryStatistics> result = new HashMap<>(); - BufferedReader bufferedReader = new BufferedReader( fileReader ); - String line = bufferedReader.readLine(); - while ( line != null ) + Map<ClassMethod, RunEntryStatistics> result = new HashMap<>(); + try ( Scanner scanner = new Scanner( fileReader, "UTF-8" ) ) { - if ( !line.startsWith( "#" ) ) + RunEntryStatistics previous = null; + while ( scanner.hasNextLine() ) { - final RunEntryStatistics stats = fromString( line ); - result.put( stats.getTestName(), stats ); + String line = scanner.nextLine(); + + if ( line.charAt( 0 ) == ' ' ) + { + previous = new RunEntryStatistics( previous.getRunTime(), + previous.getSuccessfulBuilds(), + previous.getClassMethod().getClazz(), + previous.getClassMethod().getMethod() + NL + line.substring( 1 ) ); + } + else + { + if ( previous != null ) + { + result.put( previous.getClassMethod(), previous ); + } + StringTokenizer tokenizer = new StringTokenizer( line, "," ); + + int methodIndex = 3; + + String successfulBuildsString = tokenizer.nextToken(); + int successfulBuilds = parseInt( successfulBuildsString ); + + methodIndex += successfulBuildsString.length(); + + String runTimeString = tokenizer.nextToken(); + int runTime = parseInt( runTimeString ); + + methodIndex += runTimeString.length(); + + String className = tokenizer.nextToken(); + + methodIndex += className.length(); + + String methodName = line.substring( methodIndex ); + + ClassMethod classMethod = new ClassMethod( className, methodName ); + previous = new RunEntryStatistics( runTime, successfulBuilds, classMethod ); + } + } + if ( previous != null ) + { + result.put( previous.getClassMethod(), previous ); } - line = bufferedReader.readLine(); } return new RunEntryStatisticsMap( result ); } - public void serialize( File file ) - throws FileNotFoundException + public void serialize( File statsFile ) + throws IOException { - FileOutputStream fos = new FileOutputStream( file ); - try ( PrintWriter printWriter = new PrintWriter( fos ) ) + if ( statsFile.isFile() ) + { + //noinspection ResultOfMethodCallIgnored + statsFile.delete(); + } + OutputStream os = new FileOutputStream( statsFile ); + try ( BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( os, UTF_8 ), 64 * 1024 ) ) { List<RunEntryStatistics> items = new ArrayList<>( runEntryStatistics.values() ); sort( items, new RunCountComparator() ); - for ( RunEntryStatistics item : items ) + for ( Iterator<RunEntryStatistics> it = items.iterator(); it.hasNext(); ) { - printWriter.println( item.toString() ); + RunEntryStatistics item = it.next(); + ClassMethod test = item.getClassMethod(); + String line = item.getSuccessfulBuilds() + "," + item.getRunTime() + "," + test.getClazz() + ","; + writer.write( line ); + boolean wasFirstLine = false; + for ( Scanner scanner = new Scanner( test.getMethod() ); scanner.hasNextLine(); wasFirstLine = true ) + { + String methodLine = scanner.nextLine(); + if ( wasFirstLine ) + { + writer.write( ' ' ); + } + writer.write( methodLine ); + if ( scanner.hasNextLine() ) + { + writer.newLine(); + } + } + if ( it.hasNext() ) + { + writer.newLine(); + } } } } - public RunEntryStatistics findOrCreate( ReportEntry reportEntry ) + private RunEntryStatistics findOrCreate( ReportEntry reportEntry ) { - final RunEntryStatistics item = runEntryStatistics.get( reportEntry.getName() ); - return item != null ? item : fromReportEntry( reportEntry ); + ClassMethod classMethod = new ClassMethod( reportEntry.getSourceName(), reportEntry.getName() ); + RunEntryStatistics item = runEntryStatistics.get( classMethod ); + return item != null ? item : new RunEntryStatistics( reportEntry.getElapsed( 0 ), 0, classMethod ); } public RunEntryStatistics createNextGeneration( ReportEntry reportEntry ) { - final RunEntryStatistics newItem = findOrCreate( reportEntry ); - final Integer elapsed = reportEntry.getElapsed(); - return newItem.nextGeneration( elapsed != null ? elapsed : 0 ); + RunEntryStatistics newItem = findOrCreate( reportEntry ); + return newItem.nextGeneration( reportEntry.getElapsed( 0 ) ); } public RunEntryStatistics createNextGenerationFailure( ReportEntry reportEntry ) { - final RunEntryStatistics newItem = findOrCreate( reportEntry ); - final Integer elapsed = reportEntry.getElapsed(); - return newItem.nextGenerationFailure( elapsed != null ? elapsed : 0 ); + RunEntryStatistics newItem = findOrCreate( reportEntry ); + return newItem.nextGenerationFailure( reportEntry.getElapsed( 0 ) ); } public void add( RunEntryStatistics item ) { - runEntryStatistics.put( item.getTestName(), item ); + runEntryStatistics.put( item.getClassMethod(), item ); } static final class RunCountComparator @@ -169,12 +234,12 @@ public final class RunEntryStatisticsMap private List<PrioritizedTest> getPrioritizedTests( List<Class<?>> testsToRun, Comparator<Priority> priorityComparator ) { - Map classPriorities = getPriorities( priorityComparator ); + Map<String, Priority> classPriorities = getPriorities( priorityComparator ); List<PrioritizedTest> tests = new ArrayList<>(); for ( Class<?> clazz : testsToRun ) { - Priority pri = (Priority) classPriorities.get( clazz.getName() ); + Priority pri = classPriorities.get( clazz.getName() ); if ( pri == null ) { pri = Priority.newTestClassPriority( clazz.getName() ); @@ -186,7 +251,7 @@ public final class RunEntryStatisticsMap return tests; } - private List<Class<?>> transformToClasses( List<PrioritizedTest> tests ) + private static List<Class<?>> transformToClasses( List<PrioritizedTest> tests ) { List<Class<?>> result = new ArrayList<>(); for ( PrioritizedTest test : tests ) @@ -196,22 +261,19 @@ public final class RunEntryStatisticsMap return result; } - private Map getPriorities( Comparator<Priority> priorityComparator ) + private Map<String, Priority> getPriorities( Comparator<Priority> priorityComparator ) { Map<String, Priority> priorities = new HashMap<>(); - for ( Object o : runEntryStatistics.keySet() ) + for ( Entry<ClassMethod, RunEntryStatistics> testNames : runEntryStatistics.entrySet() ) { - String testNames = (String) o; - String clazzName = extractClassName( testNames ); + String clazzName = testNames.getKey().getClazz(); Priority priority = priorities.get( clazzName ); if ( priority == null ) { priority = new Priority( clazzName ); priorities.put( clazzName, priority ); } - - RunEntryStatistics itemStat = runEntryStatistics.get( testNames ); - priority.addItem( itemStat ); + priority.addItem( testNames.getValue() ); } List<Priority> items = new ArrayList<>( priorities.values() ); @@ -255,16 +317,4 @@ public final class RunEntryStatisticsMap return o.getMinSuccessRate() - o1.getMinSuccessRate(); } } - - - private static final Pattern PARENS = Pattern.compile( "^" + "[^\\(\\)]+" //non-parens - + "\\((" // then an open-paren (start matching a group) - + "[^\\\\(\\\\)]+" //non-parens - + ")\\)" + "$" ); // then a close-paren (end group match) - - String extractClassName( String displayName ) - { - Matcher m = PARENS.matcher( displayName ); - return m.find() ? m.group( 1 ) : displayName; - } } diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/ReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/ReportEntry.java index ec0f782..e0f3468 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/report/ReportEntry.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/ReportEntry.java @@ -61,6 +61,14 @@ public interface ReportEntry */ Integer getElapsed(); + /** + * Returns same value as {@link #getElapsed()} and fallbacks to {@code fallback} for <tt>null</tt> elapsed timed. + * + * @param fallback usually 0 + * @return elapsed time if {@link #getElapsed()} is not null; otherwise returns {@code fallback} + */ + int getElapsed( int fallback ); + /** * A message relating to a non-successful termination. diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java index 241c874..4172513 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java @@ -167,6 +167,12 @@ public class SimpleReportEntry } @Override + public int getElapsed( int fallback ) + { + return elapsed == null ? fallback : elapsed; + } + + @Override public String toString() { return "ReportEntry{" + "source='" + source + '\'' + ", name='" + name + '\'' + ", stackTraceWriter=" diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ClassMethod.java similarity index 63% copy from surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java copy to surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ClassMethod.java index a3cccca..03f9620 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ClassMethod.java @@ -1,4 +1,4 @@ -package org.apache.maven.surefire.common.junit4; +package org.apache.maven.surefire.util.internal; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,7 +19,9 @@ package org.apache.maven.surefire.common.junit4; * under the License. */ -import org.apache.maven.surefire.util.internal.StringUtils; +import java.util.Objects; + +import static org.apache.maven.surefire.util.internal.StringUtils.isBlank; /** * Data transfer object of class and method literals. @@ -36,9 +38,9 @@ public final class ClassMethod this.method = method; } - public boolean isValid() + public boolean isValidTest() { - return !StringUtils.isBlank( clazz ) && !StringUtils.isBlank( method ); + return !isBlank( clazz ) && !isBlank( method ); } public String getClazz() @@ -50,4 +52,26 @@ public final class ClassMethod { return method; } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + ClassMethod that = ( ClassMethod ) o; + return Objects.equals( clazz, that.clazz ) + && Objects.equals( method, that.method ); + } + + @Override + public int hashCode() + { + return Objects.hash( clazz, method ); + } } diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/TestClassMethodNameUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/TestClassMethodNameUtils.java index 23e72e1..94bf4c8 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/TestClassMethodNameUtils.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/TestClassMethodNameUtils.java @@ -19,24 +19,15 @@ package org.apache.maven.surefire.util.internal; * under the License. */ -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * JUnit Description parser. - * Used by JUnit Version lower than 4.7. + * Used by JUnit4+. * * @author <a href="mailto:[email protected]">Tibor Digana (tibor17)</a> * @since 2.20 */ public final class TestClassMethodNameUtils { - /** - * This pattern is verbatim copy from JUnit's code in class {@code Description}. - * Parsing class and method from junit description would provide identical result to JUnit internal parser. - */ - private static final Pattern METHOD_CLASS_PATTERN = Pattern.compile( "([\\s\\S]*)\\((.*)\\)" ); - private TestClassMethodNameUtils() { throw new IllegalStateException( "no instantiable constructor" ); @@ -44,13 +35,26 @@ public final class TestClassMethodNameUtils public static String extractClassName( String displayName ) { - Matcher m = METHOD_CLASS_PATTERN.matcher( displayName ); - return m.matches() ? m.group( 2 ) : displayName; + String clazz = displayName; + if ( displayName.endsWith( ")" ) ) + { + int paren = displayName.lastIndexOf( '(' ); + if ( paren != -1 ) + { + clazz = displayName.substring( paren + 1, displayName.length() - 1 ); + } + } + return clazz; } public static String extractMethodName( String displayName ) { - Matcher m = METHOD_CLASS_PATTERN.matcher( displayName ); - return m.matches() ? m.group( 1 ) : displayName; + String method = null; + int parent = displayName.lastIndexOf( '(' ); + if ( parent != -1 ) + { + method = displayName.substring( 0, parent ); + } + return method; } } diff --git a/surefire-api/src/test/java/org/apache/maven/plugin/surefire/runorder/ThreadedExecutionSchedulerTest.java b/surefire-api/src/test/java/org/apache/maven/plugin/surefire/runorder/ThreadedExecutionSchedulerTest.java index 15963d7..6647504 100644 --- a/surefire-api/src/test/java/org/apache/maven/plugin/surefire/runorder/ThreadedExecutionSchedulerTest.java +++ b/surefire-api/src/test/java/org/apache/maven/plugin/surefire/runorder/ThreadedExecutionSchedulerTest.java @@ -21,6 +21,7 @@ package org.apache.maven.plugin.surefire.runorder; import java.util.List; import junit.framework.TestCase; +import org.apache.maven.surefire.util.internal.ClassMethod; /** * @author Kristian Rosenvold @@ -29,24 +30,23 @@ public class ThreadedExecutionSchedulerTest extends TestCase { - private final RunEntryStatistics a1 = RunEntryStatistics.fromValues( 200, 2, A.class, "at1" ); + private final RunEntryStatistics a1 = fromValues( 200, 2, A.class, "at1" ); - private final RunEntryStatistics a2 = RunEntryStatistics.fromValues( 300, 2, A.class, "at2" ); + private final RunEntryStatistics a2 = fromValues( 300, 2, A.class, "at2" ); - private final RunEntryStatistics b1 = RunEntryStatistics.fromValues( 400, 2, B.class, "bt1" ); + private final RunEntryStatistics b1 = fromValues( 400, 2, B.class, "bt1" ); - private final RunEntryStatistics b2 = RunEntryStatistics.fromValues( 300, 2, B.class, "bt2" ); + private final RunEntryStatistics b2 = fromValues( 300, 2, B.class, "bt2" ); - private final RunEntryStatistics c1 = RunEntryStatistics.fromValues( 400, 2, C.class, "ct1" ); + private final RunEntryStatistics c1 = fromValues( 400, 2, C.class, "ct1" ); - private final RunEntryStatistics c2 = RunEntryStatistics.fromValues( 200, 2, C.class, "ct2" ); + private final RunEntryStatistics c2 = fromValues( 200, 2, C.class, "ct2" ); - private final RunEntryStatistics d1 = RunEntryStatistics.fromValues( 401, 2, D.class, "ct2" ); + private final RunEntryStatistics d1 = fromValues( 401, 2, D.class, "ct2" ); - private final RunEntryStatistics e1 = RunEntryStatistics.fromValues( 200, 2, E.class, "ct2" ); + private final RunEntryStatistics e1 = fromValues( 200, 2, E.class, "ct2" ); public void testAddTest() - throws Exception { ThreadedExecutionScheduler threadedExecutionScheduler = new ThreadedExecutionScheduler( 2 ); addPrioritizedTests( threadedExecutionScheduler ); @@ -57,17 +57,14 @@ public class ThreadedExecutionSchedulerTest assertEquals( D.class, result.get( 2 ) ); assertEquals( A.class, result.get( 3 ) ); assertEquals( E.class, result.get( 4 ) ); - } public void testAddTestJaggedResult() - throws Exception { ThreadedExecutionScheduler threadedExecutionScheduler = new ThreadedExecutionScheduler( 4 ); addPrioritizedTests( threadedExecutionScheduler ); final List result = threadedExecutionScheduler.getResult(); assertEquals( 5, result.size() ); - } private void addPrioritizedTests( ThreadedExecutionScheduler threadedExecutionScheduler ) @@ -94,6 +91,11 @@ public class ThreadedExecutionSchedulerTest return priority; } + private static RunEntryStatistics fromValues( int runTime, int successfulBuilds, Class clazz, String testName ) + { + ClassMethod classMethod = new ClassMethod( clazz.getName(), testName ); + return new RunEntryStatistics( runTime, successfulBuilds, classMethod ); + } class A { diff --git a/surefire-its/pom.xml b/surefire-its/pom.xml index 0cea53e..d08d4bf 100644 --- a/surefire-its/pom.xml +++ b/surefire-its/pom.xml @@ -169,7 +169,7 @@ <forkMode>once</forkMode> <argLine>-server -Xmx64m -XX:+UseG1GC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.awt.headless=true -Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine> <includes> - <include>org/apache/**/*IT*.java</include> + <include>org/apache/**/*Platform*IT*.java</include> </includes> <!-- Pass current surefire version to the main suite so that it --> <!-- can forward to all integration test projects. SUREFIRE-513 --> diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java index 332cbb9..ae04143 100644 --- a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java +++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java @@ -59,10 +59,10 @@ public class JUnitPlatformEnginesIT public static Iterable<Object[]> regexVersions() { ArrayList<Object[]> args = new ArrayList<Object[]>(); - args.add( new Object[] { "1.0.0", "5.0.0", "1.0.0", "1.0.0" } ); + args.add( new Object[] { "1.0.3", "5.0.3", "1.0.0", "1.0.0" } ); args.add( new Object[] { "1.1.1", "5.1.1", "1.0.0", "1.0.0" } ); args.add( new Object[] { "1.2.0", "5.2.0", "1.1.0", "1.0.0" } ); - args.add( new Object[] { "1.3.1", "5.3.1", "1.1.1", "1.0.0" } ); + args.add( new Object[] { "1.3.2", "5.3.2", "1.1.1", "1.0.0" } ); args.add( new Object[] { "1.4.0-SNAPSHOT", "5.4.0-SNAPSHOT", "1.1.1", "1.0.0" } ); return args; } @@ -114,7 +114,7 @@ public class JUnitPlatformEnginesIT + " surefire-api-*.jar" + " surefire-logger-api-*.jar" + " common-java5-*.jar" - + " junit-platform-launcher-1.3.1.jar"; + + " junit-platform-launcher-1.3.2.jar"; lines = validator.loadLogLines( startsWith( "[DEBUG] provider(compact) classpath" ) ); @@ -138,7 +138,7 @@ public class JUnitPlatformEnginesIT + " opentest4j-" + opentest + ".jar" + " junit-jupiter-api-" + jupiter + ".jar" + " surefire-junit-platform-*.jar" - + " junit-platform-launcher-1.3.1.jar"; + + " junit-platform-launcher-1.3.2.jar"; lines = validator.loadLogLines( startsWith( "[DEBUG] boot(compact) classpath" ) ); diff --git a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java index 626392b..2f369e8 100644 --- a/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java +++ b/surefire-providers/common-java5/src/main/java/org/apache/maven/surefire/report/PojoStackTraceWriter.java @@ -24,6 +24,7 @@ import org.apache.maven.surefire.util.internal.StringUtils; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Objects; /** * Write the trace out for a POJO test. @@ -109,4 +110,27 @@ public class PojoStackTraceWriter } return false; } + + @Override + public boolean equals( Object o ) + { + if ( this == o ) + { + return true; + } + if ( o == null || getClass() != o.getClass() ) + { + return false; + } + PojoStackTraceWriter that = ( PojoStackTraceWriter ) o; + return Objects.equals( t, that.t ) + && Objects.equals( testClass, that.testClass ) + && Objects.equals( testMethod, that.testMethod ); + } + + @Override + public int hashCode() + { + return Objects.hash( t, testClass, testMethod ); + } } diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtil.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtil.java index d19a0e1..702ee7f 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtil.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtil.java @@ -20,14 +20,17 @@ package org.apache.maven.surefire.common.junit4; */ import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; +import org.apache.maven.surefire.util.internal.ClassMethod; import org.junit.runner.Description; import org.junit.runner.manipulation.Filter; import org.junit.runner.notification.Failure; -import static org.apache.maven.surefire.util.internal.StringUtils.isBlank; +import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName; +import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractMethodName; import static org.junit.runner.Description.TEST_MECHANISM; /** @@ -75,33 +78,30 @@ public final class JUnit4ProviderUtil * @param description method(class) or method[#](class) or method[#whatever-literals](class) * @return method JUnit test method */ - public static ClassMethod cutTestClassAndMethod( Description description ) + public static ClassMethod toClassMethod( Description description ) { - String name = description.getDisplayName(); - String clazz = null; - String method = null; - if ( name != null ) + String clazz = extractClassName( description.getDisplayName() ); + if ( clazz == null || isInsaneJunitNullString( clazz ) ) { - // The order is : 1.method and then 2.class - // method(class) - name = name.trim(); - if ( name.endsWith( ")" ) ) + // This can happen upon early failures (class instantiation error etc) + Iterator<Description> it = description.getChildren().iterator(); + if ( it.hasNext() ) { - int classBracket = name.lastIndexOf( '(' ); - if ( classBracket != -1 ) - { - clazz = tryBlank( name.substring( classBracket + 1, name.length() - 1 ) ); - method = tryBlank( name.substring( 0, classBracket ) ); - } + description = it.next(); + clazz = extractClassName( description.getDisplayName() ); + } + if ( clazz == null ) + { + clazz = "Test Instantiation Error"; } } + String method = extractMethodName( description.getDisplayName() ); return new ClassMethod( clazz, method ); } - private static String tryBlank( String s ) + private static boolean isInsaneJunitNullString( String value ) { - s = s.trim(); - return isBlank( s ) ? null : s; + return "null".equals( value ); } public static Filter createMatchAnyDescriptionFilter( Iterable<Description> descriptions ) diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java index 7ed2ad9..dc98fa9 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java @@ -24,17 +24,17 @@ import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.report.SimpleReportEntry; import org.apache.maven.surefire.report.StackTraceWriter; import org.apache.maven.surefire.testset.TestSetFailedException; +import org.apache.maven.surefire.util.internal.ClassMethod; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself; +import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod; import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue; import static org.apache.maven.surefire.report.SimpleReportEntry.assumption; import static org.apache.maven.surefire.report.SimpleReportEntry.ignored; import static org.apache.maven.surefire.report.SimpleReportEntry.withException; -import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName; -import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractMethodName; /** * RunListener for JUnit4, delegates to our own RunListener @@ -74,7 +74,8 @@ public class JUnit4RunListener throws Exception { String reason = getAnnotatedIgnoreValue( description ); - reporter.testSkipped( ignored( getClassName( description ), description.getDisplayName(), reason ) ); + ClassMethod classMethod = toClassMethod( description ); + reporter.testSkipped( ignored( classMethod.getClazz(), classMethod.getMethod(), reason ) ); } /** @@ -114,10 +115,10 @@ public class JUnit4RunListener testHeader = "Failure when constructing test"; } - String testClassName = getClassName( failure.getDescription() ); StackTraceWriter stackTrace = createStackTraceWriter( failure ); - ReportEntry report = withException( testClassName, testHeader, stackTrace ); + ClassMethod classMethod = toClassMethod( failure.getDescription() ); + ReportEntry report = withException( classMethod.getClazz(), testHeader, stackTrace ); if ( failure.getException() instanceof AssertionError ) { @@ -140,8 +141,9 @@ public class JUnit4RunListener try { Description desc = failure.getDescription(); - String test = getClassName( desc ); - reporter.testAssumptionFailure( assumption( test, desc.getDisplayName(), failure.getMessage() ) ); + ClassMethod classMethod = toClassMethod( desc ); + ReportEntry report = assumption( classMethod.getClazz(), classMethod.getMethod(), failure.getMessage() ); + reporter.testAssumptionFailure( report ); } finally { @@ -173,25 +175,6 @@ public class JUnit4RunListener reporter.testExecutionSkippedByUser(); } - private String getClassName( Description description ) - { - String name = extractDescriptionClassName( description ); - if ( name == null || isInsaneJunitNullString( name ) ) - { - // This can happen upon early failures (class instantiation error etc) - Description subDescription = description.getChildren().get( 0 ); - if ( subDescription != null ) - { - name = extractDescriptionClassName( subDescription ); - } - if ( name == null ) - { - name = "Test Instantiation Error"; - } - } - return name; - } - protected StackTraceWriter createStackTraceWriter( Failure failure ) { return new JUnit4StackTraceWriter( failure ); @@ -199,17 +182,8 @@ public class JUnit4RunListener protected SimpleReportEntry createReportEntry( Description description ) { - return new SimpleReportEntry( getClassName( description ), description.getDisplayName() ); - } - - protected String extractDescriptionClassName( Description description ) - { - return extractClassName( description.getDisplayName() ); - } - - protected String extractDescriptionMethodName( Description description ) - { - return extractMethodName( description.getDisplayName() ); + ClassMethod classMethod = toClassMethod( description ); + return new SimpleReportEntry( classMethod.getClazz(), classMethod.getMethod() ); } public static void rethrowAnyTestMechanismFailures( Result run ) diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java index 78cefb6..f60a30d 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4StackTraceWriter.java @@ -22,10 +22,10 @@ package org.apache.maven.surefire.common.junit4; import org.apache.maven.surefire.report.SafeThrowable; import org.apache.maven.surefire.report.SmartStackTraceParser; import org.apache.maven.surefire.report.StackTraceWriter; +import org.apache.maven.surefire.util.internal.ClassMethod; import org.junit.runner.notification.Failure; -import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName; -import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractMethodName; +import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod; import static org.apache.maven.surefire.report.SmartStackTraceParser.stackTraceWithFocusOnClassAsString; /** @@ -37,8 +37,7 @@ import static org.apache.maven.surefire.report.SmartStackTraceParser.stackTraceW public class JUnit4StackTraceWriter implements StackTraceWriter { - // Member Variables - protected final Failure junitFailure; + private final Failure junitFailure; /** * Constructor. @@ -78,24 +77,14 @@ public class JUnit4StackTraceWriter return ""; } - protected String getTestClassName() - { - return extractClassName( junitFailure.getDescription().getDisplayName() ); - } - - protected String getTestMethodName() - { - return extractMethodName( junitFailure.getDescription().getDisplayName() ); - } - @Override - @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" ) public String smartTrimmedStackTrace() { Throwable exception = junitFailure.getException(); + ClassMethod classMethod = toClassMethod( junitFailure.getDescription() ); return exception == null ? junitFailure.getMessage() - : new SmartStackTraceParser( getTestClassName(), exception, getTestMethodName() ).getString(); + : new SmartStackTraceParser( classMethod.getClazz(), exception, classMethod.getMethod() ).getString(); } /** @@ -106,7 +95,7 @@ public class JUnit4StackTraceWriter @Override public String writeTrimmedTraceToString() { - String testClass = getTestClassName(); + String testClass = toClassMethod( junitFailure.getDescription() ).getClazz(); try { Throwable e = junitFailure.getException(); diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/Notifier.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/Notifier.java index c2c6df8..de0ddc4 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/Notifier.java +++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/Notifier.java @@ -32,7 +32,7 @@ import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; -import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.cutTestClassAndMethod; +import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod; import static org.apache.maven.surefire.util.internal.ConcurrencyUtils.countDownToZero; /** @@ -100,7 +100,7 @@ public class Notifier super.fireTestStarted( description ); if ( !testClassNames.isEmpty() ) { - testClassNames.remove( cutTestClassAndMethod( description ).getClazz() ); + testClassNames.remove( toClassMethod( description ).getClazz() ); } } diff --git a/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtilTest.java b/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtilTest.java index 163308c..15adc32 100644 --- a/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtilTest.java +++ b/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/JUnit4ProviderUtilTest.java @@ -20,6 +20,7 @@ package org.apache.maven.surefire.common.junit4; */ import junit.framework.TestCase; +import org.apache.maven.surefire.util.internal.ClassMethod; import org.junit.runner.Description; import org.junit.runner.notification.Failure; @@ -64,25 +65,25 @@ public class JUnit4ProviderUtilTest public void testIllegalTestDescription$NegativeTest() { Description test = Description.createSuiteDescription( "someTestMethod" ); - ClassMethod classMethod = cutTestClassAndMethod( test ); - assertFalse( classMethod.isValid() ); + ClassMethod classMethod = JUnit4ProviderUtil.toClassMethod( test ); + assertFalse( classMethod.isValidTest() ); } public void testOldJUnitParameterizedDescriptionParser() { Description test = Description.createTestDescription( T1.class, " \n testMethod[5] " ); assertEquals( " \n testMethod[5] (" + T1.class.getName() + ")", test.getDisplayName() ); - ClassMethod classMethod = cutTestClassAndMethod( test ); - assertTrue( classMethod.isValid() ); - assertEquals( "testMethod[5]", classMethod.getMethod() ); + ClassMethod classMethod = JUnit4ProviderUtil.toClassMethod( test ); + assertTrue( classMethod.isValidTest() ); + assertEquals( " \n testMethod[5] ", classMethod.getMethod() ); assertEquals( T1.class.getName(), classMethod.getClazz() ); } public void testNewJUnitParameterizedDescriptionParser() { Description test = Description.createTestDescription( T1.class, "flakyTest[3: (Test11); Test12; Test13;]" ); - ClassMethod classMethod = cutTestClassAndMethod( test ); - assertTrue( classMethod.isValid() ); + ClassMethod classMethod = JUnit4ProviderUtil.toClassMethod( test ); + assertTrue( classMethod.isValidTest() ); assertEquals( "flakyTest[3: (Test11); Test12; Test13;]", classMethod.getMethod() ); assertEquals( T1.class.getName(), classMethod.getClazz() ); } diff --git a/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit46StackTraceWriter.java b/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit46StackTraceWriter.java deleted file mode 100644 index 4051e19..0000000 --- a/surefire-providers/common-junit48/src/main/java/org/apache/maven/surefire/common/junit48/JUnit46StackTraceWriter.java +++ /dev/null @@ -1,60 +0,0 @@ -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.common.junit4.JUnit4StackTraceWriter; -import org.junit.runner.notification.Failure; - -/** - * A stacktrace writer that requires at least junit 4.6 to run. Note that we only use this for 4.8 and higher - * <br> - * Writes out a specific {@link org.junit.runner.notification.Failure} for - * surefire as a stacktrace. - * - * @author Karl M. Davis - * @author Kristian Rosenvold - */ -public class JUnit46StackTraceWriter - extends JUnit4StackTraceWriter -{ - - /** - * Constructor. - * - * @param junitFailure the {@link org.junit.runner.notification.Failure} that this will be operating on - */ - public JUnit46StackTraceWriter( Failure junitFailure ) - { - super( junitFailure ); - } - - - @Override - protected final String getTestClassName() - { - return junitFailure.getDescription().getClassName(); - } - - @Override - protected String getTestMethodName() - { - return junitFailure.getDescription().getMethodName(); - } -} diff --git a/surefire-providers/surefire-junit-platform/pom.xml b/surefire-providers/surefire-junit-platform/pom.xml index 76bc92c..e551fef 100644 --- a/surefire-providers/surefire-junit-platform/pom.xml +++ b/surefire-providers/surefire-junit-platform/pom.xml @@ -139,6 +139,10 @@ <version>3.0.0-M3</version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 --> <configuration> <jvm>${java.home}/bin/java</jvm> + <redirectTestOutputToFile>true</redirectTestOutputToFile> + <includes> + <include>**/JUnit47SuiteTest.java</include> + </includes> </configuration> </plugin> </plugins> diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java index 85227f3..ce80643 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java @@ -20,17 +20,15 @@ package org.apache.maven.surefire.junitplatform; */ import static org.apache.maven.surefire.report.SimpleReportEntry.ignored; -import static org.junit.platform.engine.TestExecutionResult.Status.ABORTED; -import static org.junit.platform.engine.TestExecutionResult.Status.FAILED; +import static org.apache.maven.surefire.report.SimpleReportEntry.withException; import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.surefire.report.PojoStackTraceWriter; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.report.SimpleReportEntry; import org.apache.maven.surefire.report.StackTraceWriter; +import org.apache.maven.surefire.report.TestSetReportEntry; import org.junit.platform.engine.TestExecutionResult; import org.junit.platform.engine.TestSource; import org.junit.platform.engine.support.descriptor.ClassSource; @@ -38,7 +36,6 @@ import org.junit.platform.engine.support.descriptor.MethodSource; import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.TestPlan; -import org.junit.platform.launcher.listeners.LegacyReportingUtils; /** * @since 2.22.0 @@ -46,12 +43,9 @@ import org.junit.platform.launcher.listeners.LegacyReportingUtils; final class RunListenerAdapter implements TestExecutionListener { - private final RunListener runListener; - private TestPlan testPlan; - - private Set<TestIdentifier> testSetNodes = ConcurrentHashMap.newKeySet(); + private volatile TestPlan testPlan; RunListenerAdapter( RunListener runListener ) { @@ -61,13 +55,13 @@ final class RunListenerAdapter @Override public void testPlanExecutionStarted( TestPlan testPlan ) { - updateTestPlan( testPlan ); + this.testPlan = testPlan; } @Override public void testPlanExecutionFinished( TestPlan testPlan ) { - updateTestPlan( null ); + this.testPlan = null; } @Override @@ -76,117 +70,82 @@ final class RunListenerAdapter if ( testIdentifier.isContainer() && testIdentifier.getSource().filter( ClassSource.class::isInstance ).isPresent() ) { - startTestSetIfPossible( testIdentifier ); + runListener.testSetStarting( createTestSetReportEntry( testIdentifier ) ); } - if ( testIdentifier.isTest() ) + else if ( testIdentifier.isTest() ) { - ensureTestSetStarted( testIdentifier ); runListener.testStarting( createReportEntry( testIdentifier ) ); } } @Override - public void executionSkipped( TestIdentifier testIdentifier, String reason ) - { - ensureTestSetStarted( testIdentifier ); - String source = getLegacyReportingClassName( testIdentifier ); - runListener.testSkipped( ignored( source, getLegacyReportingName( testIdentifier ), reason ) ); - completeTestSetIfNecessary( testIdentifier ); - } - - @Override - public void executionFinished( - TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) - { - if ( testExecutionResult.getStatus() == ABORTED ) - { - runListener.testAssumptionFailure( createReportEntry( testIdentifier, testExecutionResult ) ); - } - else if ( testExecutionResult.getStatus() == FAILED ) - { - reportFailedTest( testIdentifier, testExecutionResult ); - } - else if ( testIdentifier.isTest() ) - { - runListener.testSucceeded( createReportEntry( testIdentifier ) ); - } - completeTestSetIfNecessary( testIdentifier ); - } - - private void updateTestPlan( TestPlan testPlan ) - { - this.testPlan = testPlan; - testSetNodes.clear(); - } - - private void ensureTestSetStarted( TestIdentifier testIdentifier ) - { - if ( isTestSetStarted( testIdentifier ) ) - { - return; - } - if ( testIdentifier.isTest() ) - { - startTestSet( testPlan.getParent( testIdentifier ).orElse( testIdentifier ) ); - } - else - { - startTestSet( testIdentifier ); + public void executionFinished( TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) + { + boolean isClass = testIdentifier.isContainer() + && testIdentifier.getSource().filter( ClassSource.class::isInstance ).isPresent(); + + boolean isTest = testIdentifier.isTest(); + + if ( isClass || isTest ) + { + switch ( testExecutionResult.getStatus() ) + { + case ABORTED: + TestSetReportEntry reportEntry = createReportEntry( testIdentifier, testExecutionResult ); + if ( isTest ) + { + runListener.testAssumptionFailure( reportEntry ); + } + else + { + runListener.testSetCompleted( reportEntry ); + } + break; + case FAILED: + reportEntry = createReportEntry( testIdentifier, testExecutionResult ); + if ( !isTest ) + { + runListener.testSetCompleted( reportEntry ); + } + else if ( testExecutionResult.getThrowable() + .filter( AssertionError.class::isInstance ).isPresent() ) + { + runListener.testFailed( reportEntry ); + } + else + { + runListener.testError( reportEntry ); + } + break; + default: + reportEntry = createReportEntry( testIdentifier ); + if ( isTest ) + { + runListener.testSucceeded( reportEntry ); + } + else + { + runListener.testSetCompleted( reportEntry ); + } + } } } - private boolean isTestSetStarted( TestIdentifier testIdentifier ) - { - return testSetNodes.contains( testIdentifier ) - || testPlan.getParent( testIdentifier ).map( this::isTestSetStarted ).orElse( false ); - } - - private void startTestSetIfPossible( TestIdentifier testIdentifier ) - { - if ( !isTestSetStarted( testIdentifier ) ) - { - startTestSet( testIdentifier ); - } - } - - private void completeTestSetIfNecessary( TestIdentifier testIdentifier ) - { - if ( testSetNodes.contains( testIdentifier ) ) - { - completeTestSet( testIdentifier ); - } - } - - private void startTestSet( TestIdentifier testIdentifier ) - { - runListener.testSetStarting( createTestSetReportEntry( testIdentifier ) ); - testSetNodes.add( testIdentifier ); - } - - private void completeTestSet( TestIdentifier testIdentifier ) + @Override + public void executionSkipped( TestIdentifier testIdentifier, String reason ) { - runListener.testSetCompleted( createTestSetReportEntry( testIdentifier ) ); - testSetNodes.remove( testIdentifier ); - } - - private void reportFailedTest( - TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) - { - SimpleReportEntry reportEntry = createReportEntry( testIdentifier, testExecutionResult ); - if ( testExecutionResult.getThrowable().filter( AssertionError.class::isInstance ).isPresent() ) - { - runListener.testFailed( reportEntry ); - } - else - { - runListener.testError( reportEntry ); - } + String[] classMethodName = toClassMethodName( testIdentifier ); + String className = classMethodName[0]; + String methodName = classMethodName[1]; + runListener.testSkipped( ignored( className, methodName, reason ) ); } private SimpleReportEntry createTestSetReportEntry( TestIdentifier testIdentifier ) { - return new SimpleReportEntry( - JUnitPlatformProvider.class.getName(), testIdentifier.getLegacyReportingName() ); + String[] classMethodName = toClassMethodName( testIdentifier ); + String className = classMethodName[0]; + String methodName = classMethodName[1]; + return new SimpleReportEntry( className, methodName ); } private SimpleReportEntry createReportEntry( TestIdentifier testIdentifier ) @@ -194,79 +153,88 @@ final class RunListenerAdapter return createReportEntry( testIdentifier, (StackTraceWriter) null ); } - private SimpleReportEntry createReportEntry( - TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) - { - return createReportEntry( - testIdentifier, getStackTraceWriter( testIdentifier, testExecutionResult ) ); - } - - private SimpleReportEntry createReportEntry( - TestIdentifier testIdentifier, StackTraceWriter stackTraceWriter ) - { - String source = getLegacyReportingClassName( testIdentifier ); - String name = getLegacyReportingName( testIdentifier ); - - return SimpleReportEntry.withException( source, name, stackTraceWriter ); - } - - private String getLegacyReportingName( TestIdentifier testIdentifier ) + private SimpleReportEntry createReportEntry( TestIdentifier testIdentifier, + TestExecutionResult testExecutionResult ) { - // Surefire cuts off the name at the first '(' character. Thus, we have to pick a different - // character to represent parentheses. "()" are removed entirely to maximize compatibility with - // existing reporting tools because in the old days test methods used to not have parameters. - return testIdentifier - .getLegacyReportingName() - .replace( "()", "" ) - .replace( '(', '{' ) - .replace( ')', '}' ); + return createReportEntry( testIdentifier, toStackTraceWriter( testIdentifier, testExecutionResult ) ); } - private String getLegacyReportingClassName( TestIdentifier testIdentifier ) + private SimpleReportEntry createReportEntry( TestIdentifier testIdentifier, StackTraceWriter stackTraceWriter ) { - return LegacyReportingUtils.getClassName( testPlan, testIdentifier ); + String[] classMethodName = toClassMethodName( testIdentifier ); + String className = classMethodName[0]; + String methodName = classMethodName[1]; + return withException( className, methodName, stackTraceWriter ); } - private StackTraceWriter getStackTraceWriter( - TestIdentifier testIdentifier, TestExecutionResult testExecutionResult ) + private StackTraceWriter toStackTraceWriter( TestIdentifier testIdentifier, + TestExecutionResult testExecutionResult ) { - Optional<Throwable> throwable = testExecutionResult.getThrowable(); - if ( testExecutionResult.getStatus() == FAILED ) + switch ( testExecutionResult.getStatus() ) { - // Failed tests must have a StackTraceWriter, otherwise Surefire will fail - return getStackTraceWriter( testIdentifier, throwable.orElse( null ) ); + case ABORTED: + case FAILED: + // Failed tests must have a StackTraceWriter, otherwise Surefire will fail + return toStackTraceWriter( testIdentifier, testExecutionResult.getThrowable().orElse( null ) ); + default: + return testExecutionResult.getThrowable().map( t -> toStackTraceWriter( testIdentifier, t ) ) + .orElse( null ); } - return throwable.map( t -> getStackTraceWriter( testIdentifier, t ) ).orElse( null ); } - private StackTraceWriter getStackTraceWriter( TestIdentifier testIdentifier, Throwable throwable ) + private StackTraceWriter toStackTraceWriter( TestIdentifier testIdentifier, Throwable throwable ) { - String className = getClassName( testIdentifier ); - String methodName = getMethodName( testIdentifier ).orElse( "" ); + String[] classMethodName = toClassMethodName( testIdentifier ); + String className = classMethodName[0]; + String methodName = classMethodName[1]; return new PojoStackTraceWriter( className, methodName, throwable ); } - private String getClassName( TestIdentifier testIdentifier ) + /** + * <ul> + * <li>[0] class name - used in stacktrace parser</li> + * <li>[1] class display name</li> + * <li>[2] method signature - used in stacktrace parser</li> + * <li>[3] method display name</li> + * </ul> + * + * @param testIdentifier a class or method + * @return 4 elements string array + */ + private String[] toClassMethodName( TestIdentifier testIdentifier ) { - TestSource testSource = testIdentifier.getSource().orElse( null ); - if ( testSource instanceof ClassSource ) + Optional<TestSource> testSource = testIdentifier.getSource(); + String display = testIdentifier.getDisplayName(); + + if ( testSource.filter( MethodSource.class::isInstance ).isPresent() ) { - return ( (ClassSource) testSource ).getJavaClass().getName(); + MethodSource methodSource = testSource.map( MethodSource.class::cast ).get(); + + String source = testPlan.getParent( testIdentifier ) + .map( this::toClassMethodName ) + .map( s -> s[0] ) + .orElse( methodSource.getClassName() ); + + String method = methodSource.getMethodName(); + boolean useMethod = display.equals( method ) || display.equals( method + "()" ); + String name = useMethod ? method : display; + + return new String[] { source, name }; } - if ( testSource instanceof MethodSource ) + else if ( testSource.filter( ClassSource.class::isInstance ).isPresent() ) { - return ( (MethodSource) testSource ).getClassName(); + ClassSource classSource = testSource.map( ClassSource.class::cast ).get(); + String className = classSource.getClassName(); + String simpleClassName = className.substring( 1 + className.lastIndexOf( '.' ) ); + String source = display.equals( simpleClassName ) ? className : display; + return new String[] { source, source }; } - return testPlan.getParent( testIdentifier ).map( this::getClassName ).orElse( "" ); - } - - private Optional<String> getMethodName( TestIdentifier testIdentifier ) - { - TestSource testSource = testIdentifier.getSource().orElse( null ); - if ( testSource instanceof MethodSource ) + else { - return Optional.of( ( (MethodSource) testSource ).getMethodName() ); + String source = testPlan.getParent( testIdentifier ) + .map( TestIdentifier::getDisplayName ) + .orElse( display ); + return new String[] { source, display }; } - return Optional.empty(); } } diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java similarity index 56% rename from surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java rename to surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java index a3cccca..d0d4af9 100644 --- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/ClassMethod.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnit47SuiteTest.java @@ -1,4 +1,4 @@ -package org.apache.maven.surefire.common.junit4; +package org.apache.maven.surefire.junitplatform; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -19,35 +19,28 @@ package org.apache.maven.surefire.common.junit4; * under the License. */ -import org.apache.maven.surefire.util.internal.StringUtils; +import junit.framework.JUnit4TestAdapter; +import junit.framework.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; /** - * Data transfer object of class and method literals. + * Adapt the JUnit4 tests which use only annotations to the JUnit3 test suite. + * + * @since 3.0.0-M4 */ -public final class ClassMethod +@SuiteClasses( { + JUnitPlatformProviderTest.class, + RunListenerAdapterTest.class, + TestMethodFilterTest.class, + TestPlanScannerFilterTest.class +} ) +@RunWith( Suite.class ) +public class JUnit47SuiteTest { - private final String clazz; - - private final String method; - - public ClassMethod( String clazz, String method ) - { - this.clazz = clazz; - this.method = method; - } - - public boolean isValid() - { - return !StringUtils.isBlank( clazz ) && !StringUtils.isBlank( method ); - } - - public String getClazz() - { - return clazz; - } - - public String getMethod() + public static Test suite() { - return method; + return new JUnit4TestAdapter( JUnit47SuiteTest.class ); } } diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java index c162905..7aa8011 100644 --- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java @@ -167,25 +167,25 @@ public class JUnitPlatformProviderTest .verify( runListener ) .testSetStarting( new SimpleReportEntry( - JUnitPlatformProvider.class.getName(), + TestClass1.class.getName(), TestClass1.class.getName() ) ); inOrder .verify( runListener ) .testSetCompleted( new SimpleReportEntry( - JUnitPlatformProvider.class.getName(), + TestClass1.class.getName(), TestClass1.class.getName() ) ); inOrder .verify( runListener ) .testSetStarting( new SimpleReportEntry( - JUnitPlatformProvider.class.getName(), + TestClass2.class.getName(), TestClass2.class.getName() ) ); inOrder .verify( runListener ) .testSetCompleted( new SimpleReportEntry( - JUnitPlatformProvider.class.getName(), + TestClass2.class.getName(), TestClass2.class.getName() ) ); assertThat( executionListener.summaries ).hasSize( 1 ); diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTest.java index 0ccb4fe..73f108c 100644 --- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTest.java +++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/RunListenerAdapterTest.java @@ -22,15 +22,18 @@ package org.apache.maven.surefire.junitplatform; import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static java.util.Collections.singletonList; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.platform.engine.TestDescriptor.Type.CONTAINER; import static org.junit.platform.engine.TestDescriptor.Type.TEST; +import static org.junit.platform.engine.TestExecutionResult.aborted; +import static org.junit.platform.engine.TestExecutionResult.failed; import static org.junit.platform.engine.TestExecutionResult.successful; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.inOrder; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -38,11 +41,15 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; +import java.lang.reflect.Method; import java.util.Optional; +import org.apache.maven.surefire.report.PojoStackTraceWriter; import org.apache.maven.surefire.report.ReportEntry; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.report.SimpleReportEntry; +import org.apache.maven.surefire.report.StackTraceWriter; +import org.apache.maven.surefire.report.TestSetReportEntry; import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.DisplayName; @@ -51,16 +58,16 @@ import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor; import org.junit.platform.engine.ConfigurationParameters; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.TestDescriptor.Type; -import org.junit.platform.engine.TestExecutionResult; import org.junit.platform.engine.TestSource; import org.junit.platform.engine.UniqueId; import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor; import org.junit.platform.engine.support.descriptor.ClassSource; import org.junit.platform.engine.support.descriptor.EngineDescriptor; +import org.junit.platform.engine.support.descriptor.MethodSource; import org.junit.platform.launcher.TestIdentifier; import org.junit.platform.launcher.TestPlan; import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; +import org.opentest4j.TestSkippedException; /** * Unit tests for {@link RunListenerAdapter}. @@ -69,7 +76,7 @@ import org.mockito.InOrder; */ public class RunListenerAdapterTest { - private static final ConfigurationParameters CONFIG_PARAMS = mock(ConfigurationParameters.class); + private static final ConfigurationParameters CONFIG_PARAMS = mock( ConfigurationParameters.class ); private RunListener listener; @@ -120,7 +127,7 @@ public class RunListenerAdapterTest verify( listener ).testStarting( entryCaptor.capture() ); ReportEntry entry = entryCaptor.getValue(); - assertEquals( MY_TEST_METHOD_NAME + "{String}", entry.getName() ); + assertEquals( MY_TEST_METHOD_NAME + "(String)", entry.getName() ); assertEquals( MyTestClass.class.getName(), entry.getSourceName() ); assertNull( entry.getStackTraceWriter() ); } @@ -139,7 +146,7 @@ public class RunListenerAdapterTest adapter.testPlanExecutionStarted( plan ); adapter.executionStarted( TestIdentifier.from( engine ) ); adapter.executionStarted( TestIdentifier.from( parent ) ); - verify( listener ).testSetStarting( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), + verify( listener ).testSetStarting( new SimpleReportEntry( MyTestClass.class.getName(), MyTestClass.class.getName() ) ); verifyNoMoreInteractions( listener ); @@ -152,7 +159,7 @@ public class RunListenerAdapterTest verifyNoMoreInteractions( listener ); adapter.executionFinished( TestIdentifier.from( parent ), successful() ); - verify( listener ).testSetCompleted( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), + verify( listener ).testSetCompleted( new SimpleReportEntry( MyTestClass.class.getName(), MyTestClass.class.getName() ) ); verifyNoMoreInteractions( listener ); @@ -161,11 +168,10 @@ public class RunListenerAdapterTest } @Test - public void notifiedLazilyForTestSetWhenFirstTestWithoutClassDescriptorParentStarted() + public void displayNamesInClassAndMethods() { EngineDescriptor engine = newEngineDescriptor(); - TestDescriptor parent = newTestDescriptor( engine.getUniqueId().append( "container", "noClass" ), "parent", - CONTAINER ); + TestDescriptor parent = newClassDescriptor( "parent" ); engine.addChild( parent ); TestDescriptor child1 = newTestDescriptor( parent.getUniqueId().append( "test", "child1" ), "child1", TEST ); parent.addChild( child1 ); @@ -176,14 +182,12 @@ public class RunListenerAdapterTest adapter.testPlanExecutionStarted( plan ); adapter.executionStarted( TestIdentifier.from( engine ) ); adapter.executionStarted( TestIdentifier.from( parent ) ); + verify( listener ).testSetStarting( new SimpleReportEntry( "parent", "parent" ) ); verifyZeroInteractions( listener ); adapter.executionStarted( TestIdentifier.from( child1 ) ); - InOrder inOrder = inOrder( listener ); - inOrder.verify( listener ) - .testSetStarting( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), "parent" ) ); - inOrder.verify( listener ).testStarting( new SimpleReportEntry( "parent", "child1" ) ); - inOrder.verifyNoMoreInteractions(); + verify( listener ).testStarting( new SimpleReportEntry( "parent", "child1" ) ); + verifyNoMoreInteractions( listener ); adapter.executionFinished( TestIdentifier.from( child1 ), successful() ); verify( listener ).testSucceeded( new SimpleReportEntry( "parent", "child1" ) ); @@ -198,8 +202,7 @@ public class RunListenerAdapterTest verifyNoMoreInteractions( listener ); adapter.executionFinished( TestIdentifier.from( parent ), successful() ); - verify( listener ) - .testSetCompleted( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), "parent" ) ); + verify( listener ).testSetCompleted( new SimpleReportEntry( "parent", "parent" ) ); verifyNoMoreInteractions( listener ); adapter.executionFinished( TestIdentifier.from( engine ), successful() ); @@ -207,7 +210,7 @@ public class RunListenerAdapterTest } @Test - public void notifiedForTestSetForSingleNodeEngine() + public void notifiedForUnclassifiedTestIdentifier() { EngineDescriptor engine = new EngineDescriptor( UniqueId.forEngine( "engine" ), "engine" ) { @@ -221,18 +224,12 @@ public class RunListenerAdapterTest adapter.testPlanExecutionStarted( plan ); adapter.executionStarted( TestIdentifier.from( engine ) ); - InOrder inOrder = inOrder( listener ); - inOrder.verify( listener ) - .testSetStarting( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), "engine" ) ); - inOrder.verify( listener ).testStarting( new SimpleReportEntry( "<unrooted>", "engine" ) ); - inOrder.verifyNoMoreInteractions(); + verify( listener ).testStarting( new SimpleReportEntry( "engine", "engine" ) ); + verifyNoMoreInteractions( listener ); adapter.executionFinished( TestIdentifier.from( engine ), successful() ); - inOrder = inOrder( listener ); - inOrder.verify( listener ).testSucceeded( new SimpleReportEntry( "<unrooted>", "engine" ) ); - inOrder.verify( listener ) - .testSetCompleted( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), "engine" ) ); - inOrder.verifyNoMoreInteractions(); + verify( listener ).testSucceeded( new SimpleReportEntry( "engine", "engine" ) ); + verifyNoMoreInteractions( listener ); } @Test @@ -279,48 +276,54 @@ public class RunListenerAdapterTest public void notifiedWhenMethodExecutionAborted() throws Exception { - adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.aborted( null ) ); + adapter.executionFinished( newMethodIdentifier(), aborted( null ) ); verify( listener ).testAssumptionFailure( any() ); } @Test public void notifiedWhenClassExecutionAborted() { - adapter.executionFinished( newClassIdentifier(), TestExecutionResult.aborted( null ) ); - verify( listener ).testAssumptionFailure( any() ); + TestSkippedException t = new TestSkippedException( "skipped" ); + adapter.executionFinished( newClassIdentifier(), aborted( t ) ); + String name = MyTestClass.class.getName(); + StackTraceWriter stw = new PojoStackTraceWriter( name, name, t ); + verify( listener ).testSetCompleted( eq( new SimpleReportEntry( name, name, stw, null ) ) ); } @Test - public void notifiedWhenMethodExecutionFailedWithAnAssertionError() + public void notifiedWhenMethodExecutionFailed() throws Exception { - adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.failed( new AssertionError() ) ); + adapter.executionFinished( newMethodIdentifier(), failed( new AssertionError() ) ); verify( listener ).testFailed( any() ); } @Test - public void notifiedWhenMethodExecutionFailedWithANonAssertionError() + public void notifiedWhenMethodExecutionFailedWithError() throws Exception { - adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.failed( new RuntimeException() ) ); + adapter.executionFinished( newMethodIdentifier(), failed( new RuntimeException() ) ); verify( listener ).testError( any() ); } @Test public void notifiedWithCorrectNamesWhenClassExecutionFailed() { - ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); + ArgumentCaptor<TestSetReportEntry> entryCaptor = ArgumentCaptor.forClass( TestSetReportEntry.class ); TestPlan testPlan = TestPlan.from( singletonList( new EngineDescriptor( newId(), "Luke's Plan" ) ) ); adapter.testPlanExecutionStarted( testPlan ); - adapter.executionFinished( - identifiersAsParentOnTestPlan( testPlan, newEngineDescriptor(), newClassDescriptor() ), - TestExecutionResult.failed( new AssertionError() ) ); - verify( listener ).testFailed( entryCaptor.capture() ); + adapter.executionFinished( identifiersAsParentOnTestPlan( testPlan, newClassDescriptor() ), + failed( new AssertionError() ) ); + verify( listener ).testSetCompleted( entryCaptor.capture() ); ReportEntry entry = entryCaptor.getValue(); assertEquals( MyTestClass.class.getTypeName(), entry.getSourceName() ); + assertEquals( MyTestClass.class.getTypeName(), entry.getName() ); assertNotNull( entry.getStackTraceWriter() ); + assertNotNull( entry.getStackTraceWriter().getThrowable() ); + assertThat( entry.getStackTraceWriter().getThrowable().getTarget() ) + .isInstanceOf( AssertionError.class ); } @Test @@ -342,7 +345,7 @@ public class RunListenerAdapterTest adapter.executionFinished( TestIdentifier.from( classDescriptor ), successful() ); - verify( listener ).testSetCompleted( new SimpleReportEntry( JUnitPlatformProvider.class.getName(), + verify( listener ).testSetCompleted( new SimpleReportEntry( MyTestClass.class.getName(), MyTestClass.class.getName() ) ); verify( listener, never() ).testSucceeded( any() ); @@ -375,7 +378,7 @@ public class RunListenerAdapterTest TestIdentifier child = newSourcelessChildIdentifierWithParent( plan, "Parent", ClassSource.from( MyTestClass.class ) ); - adapter.executionFinished( child, TestExecutionResult.failed( new RuntimeException() ) ); + adapter.executionFinished( child, failed( new RuntimeException() ) ); ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); verify( listener ).testError( entryCaptor.capture() ); assertNotNull( entryCaptor.getValue().getStackTraceWriter() ); @@ -388,7 +391,7 @@ public class RunListenerAdapterTest adapter.testPlanExecutionStarted( plan ); TestIdentifier child = newSourcelessChildIdentifierWithParent( plan, "Parent", null ); - adapter.executionFinished( child, TestExecutionResult.failed( new RuntimeException( "message" ) ) ); + adapter.executionFinished( child, failed( new RuntimeException( "message" ) ) ); ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); verify( listener ).testError( entryCaptor.capture() ); assertNotNull( entryCaptor.getValue().getStackTraceWriter() ); @@ -401,7 +404,7 @@ public class RunListenerAdapterTest public void stackTraceWriterPresentEvenWithoutException() throws Exception { - adapter.executionFinished( newMethodIdentifier(), TestExecutionResult.failed( null ) ); + adapter.executionFinished( newMethodIdentifier(), failed( null ) ); ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); verify( listener ).testError( entryCaptor.capture() ); assertNotNull( entryCaptor.getValue().getStackTraceWriter() ); @@ -411,8 +414,22 @@ public class RunListenerAdapterTest public void displayNamesIgnoredInReport() throws NoSuchMethodException { - TestMethodTestDescriptor descriptor = new TestMethodTestDescriptor( newId(), MyTestClass.class, - MyTestClass.class.getDeclaredMethod( "myNamedTestMethod" ) ); + class TestMethodTestDescriptorWithDisplayName extends AbstractTestDescriptor + { + private TestMethodTestDescriptorWithDisplayName( UniqueId uniqueId, Class<?> testClass, Method testMethod ) + { + super( uniqueId, "some display name", MethodSource.from( testClass, testMethod ) ); + } + + @Override + public Type getType() + { + return Type.TEST; + } + } + + TestMethodTestDescriptorWithDisplayName descriptor = new TestMethodTestDescriptorWithDisplayName( newId(), + MyTestClass.class, MyTestClass.class.getDeclaredMethod( "myNamedTestMethod" ) ); TestIdentifier factoryIdentifier = TestIdentifier.from( descriptor ); ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass( ReportEntry.class ); @@ -422,7 +439,7 @@ public class RunListenerAdapterTest ReportEntry value = entryCaptor.getValue(); - assertEquals( "myNamedTestMethod", value.getName() ); + assertEquals( "some display name", value.getName() ); } private static TestIdentifier newMethodIdentifier() @@ -445,6 +462,12 @@ public class RunListenerAdapterTest return TestIdentifier.from( newClassDescriptor() ); } + private static TestDescriptor newClassDescriptor( String displayName ) + { + return new ClassTestDescriptor( UniqueId.root( "class", MyTestClass.class.getName() ), + c -> displayName, MyTestClass.class, CONFIG_PARAMS ) {}; + } + private static TestDescriptor newClassDescriptor() { return new ClassTestDescriptor( UniqueId.root( "class", MyTestClass.class.getName() ), MyTestClass.class, CONFIG_PARAMS ); @@ -516,6 +539,13 @@ public class RunListenerAdapterTest return childIdentifier; } + private static TestIdentifier identifiersAsParentOnTestPlan( TestPlan plan, TestDescriptor root ) + { + TestIdentifier rootIdentifier = TestIdentifier.from( root ); + plan.add( rootIdentifier ); + return rootIdentifier; + } + private static UniqueId newId() { return UniqueId.forEngine( "engine" ); diff --git a/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java b/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java index 977ac9e..fad855e 100644 --- a/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java +++ b/surefire-providers/surefire-junit3/src/test/java/org/apache/maven/surefire/junit/JUnitTestSetTest.java @@ -42,10 +42,10 @@ public class JUnitTestSetTest JUnitTestSet testSet = new JUnitTestSet( Suite.class, reflector ); SuccessListener listener = new SuccessListener(); testSet.execute( listener, testClassLoader ); - List succeededTests = listener.getSucceededTests(); + List<ReportEntry> succeededTests = listener.getSucceededTests(); assertEquals( 1, succeededTests.size() ); assertEquals( "testSuccess(org.apache.maven.surefire.junit.JUnitTestSetTest$AlwaysSucceeds)", - ( (ReportEntry) succeededTests.get( 0 ) ).getName() ); + succeededTests.get( 0 ).getName() ); } public static final class AlwaysSucceeds @@ -81,7 +81,7 @@ public class JUnitTestSetTest @Override public void testSucceeded( ReportEntry report ) { - this.succeededTests.add( report ); + succeededTests.add( report ); } @Override @@ -118,7 +118,7 @@ public class JUnitTestSetTest testSkipped( report ); } - public List getSucceededTests() + List<ReportEntry> getSucceededTests() { return succeededTests; } diff --git a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/TestResolverFilter.java b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/TestResolverFilter.java index 4205b14..72669a8 100644 --- a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/TestResolverFilter.java +++ b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/TestResolverFilter.java @@ -1 +1 @@ -package org.apache.maven.surefire.junit4; /* * 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.common.junit4.ClassMethod; import org.apache.maven.surefire.testset.TestListResolver; import org.junit.runner. Description; import org.junit.runner.manipulation.Filter; import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.cutTestClassAndMethod; import static org.apache.maven.surefire.testset.TestListResolver.toClassFileName; /** * Method filter used in {@link JUnit4Provider}. */ final class TestResolverFilter extends Filter { private final TestListResolver methodFilter; TestResolverFilter( TestListResolver methodFilter ) { this.methodFilter = methodFilter; } @Override public boolean shouldRun( Description description ) { // class: Java class name; method: 1. "testMethod" or 2. "testMethod[5+whatever]" in @Parameterized final ClassMethod cm = cutTestClassAndMethod( description ); final boolean isSuite = description.isSuite(); final boolean isValidTest = description.isTest() && cm.isValid(); final String clazz = cm.getClazz(); final String method = cm.getMethod(); return is Suite || isValidTest && methodFilter.shouldRun( toClassFileName( clazz ), method ); } @Override public String describe() { return methodFilter.toString(); } } \ No newline at end of file +package org.apache.maven.surefire.junit4; /* * 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.internal.ClassMethod; import org.apache.maven.surefire.testset.TestListResolver; import org.junit.runner. Description; import org.junit.runner.manipulation.Filter; import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod; import static org.apache.maven.surefire.testset.TestListResolver.toClassFileName; /** * Method filter used in {@link JUnit4Provider}. */ final class TestResolverFilter extends Filter { private final TestListResolver methodFilter; TestResolverFilter( TestListResolver methodFilter ) { this.methodFilter = methodFilter; } @Override public boolean shouldRun( Description description ) { // class: Java class name; method: 1. "testMethod" or 2. "testMethod[5+whatever]" in @Parameterized final ClassMethod cm = toClassMethod( description ); final boolean isSuite = description.isSuite(); final boolean isValidTest = description.isTest() && cm.isValidTest(); final String clazz = cm.getClazz(); final String method = cm.getMethod(); return isSuite || isV alidTest && methodFilter.shouldRun( toClassFileName( clazz ), method ); } @Override public String describe() { return methodFilter.toString(); } } \ No newline at end of file diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java index ae00fdb..03e314e 100644 --- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java +++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java @@ -20,7 +20,7 @@ package org.apache.maven.surefire.junitcore; */ import org.apache.maven.surefire.common.junit4.JUnit4RunListener; -import org.apache.maven.surefire.common.junit48.JUnit46StackTraceWriter; +import org.apache.maven.surefire.common.junit4.JUnit4StackTraceWriter; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.report.StackTraceWriter; import org.junit.runner.Description; @@ -29,6 +29,8 @@ import org.junit.runner.notification.Failure; import java.util.Map; +import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName; + /** * Noteworthy things about JUnit4 listening: * <br> @@ -95,7 +97,7 @@ public class JUnitCoreRunListener { if ( description.isTest() ) { - final String testClassName = extractDescriptionClassName( description ); + final String testClassName = extractClassName( description.getDisplayName() ); if ( testClassName != null ) { final TestSet testSet; @@ -121,18 +123,6 @@ public class JUnitCoreRunListener @Override protected StackTraceWriter createStackTraceWriter( Failure failure ) { - return new JUnit46StackTraceWriter( failure ); - } - - @Override - protected String extractDescriptionClassName( Description description ) - { - return description.getClassName(); - } - - @Override - protected String extractDescriptionMethodName( Description description ) - { - return description.getMethodName(); + return new JUnit4StackTraceWriter( failure ); } } diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java index f8d2fb7..71ec93d 100644 --- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java +++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java @@ -19,6 +19,7 @@ package org.apache.maven.surefire.junitcore; * under the License. */ +import org.apache.maven.surefire.util.internal.ClassMethod; import org.apache.maven.surefire.common.junit4.JUnit4RunListener; import org.apache.maven.surefire.report.ConsoleOutputReceiver; import org.apache.maven.surefire.report.RunListener; @@ -32,6 +33,7 @@ import org.junit.runner.notification.Failure; import java.util.Collections; import java.util.Map; +import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod; import static org.apache.maven.surefire.util.internal.ObjectUtils.systemProps; /** @@ -63,13 +65,14 @@ public class NonConcurrentRunListener @Override protected SimpleReportEntry createReportEntry( Description description ) { - return new SimpleReportEntry( extractDescriptionClassName( description ), description.getDisplayName() ); + ClassMethod classMethod = toClassMethod( description ); + return new SimpleReportEntry( classMethod.getClazz(), classMethod.getMethod() ); } private TestSetReportEntry createReportEntryForTestSet( Description description, Map<String, String> systemProps ) { - String testClassName = extractDescriptionClassName( description ); - return new SimpleReportEntry( testClassName, testClassName, systemProps ); + ClassMethod classMethod = toClassMethod( description ); + return new SimpleReportEntry( classMethod.getClazz(), classMethod.getClazz(), systemProps ); } private TestSetReportEntry createTestSetReportEntryStarted( Description description ) @@ -83,18 +86,6 @@ public class NonConcurrentRunListener } @Override - protected String extractDescriptionClassName( Description description ) - { - return description.getClassName(); - } - - @Override - protected String extractDescriptionMethodName( Description description ) - { - return description.getMethodName(); - } - - @Override public void testStarted( Description description ) throws Exception { diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListenerTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListenerTest.java index b467f63..08bbd2a 100644 --- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListenerTest.java +++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListenerTest.java @@ -43,7 +43,6 @@ public class JUnitCoreRunListenerTest extends TestCase { public void testTestRunStarted() - throws Exception { RunListener jUnit4TestSetReporter = new JUnitCoreRunListener( new MockReporter(), new HashMap<String, TestSet>() ); @@ -55,7 +54,6 @@ public class JUnitCoreRunListenerTest } public void testFailedAssumption() - throws Exception { RunListener jUnit4TestSetReporter = new JUnitCoreRunListener( new MockReporter(), new HashMap<String, TestSet>() ); diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java index 19cd22d..8cb7641 100644 --- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java +++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGReporter.java @@ -25,6 +25,7 @@ import org.apache.maven.surefire.report.ReportEntry; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.report.SimpleReportEntry; +import org.testng.IClass; import org.testng.ISuite; import org.testng.ISuiteListener; import org.testng.ITestContext; @@ -64,54 +65,45 @@ public class TestNGReporter @Override public void onTestStart( ITestResult result ) { - String group = groupString( result.getMethod().getGroups(), result.getTestClass().getName() ); - String userFriendlyTestName = getUserFriendlyTestName( result ); - reporter.testStarting( new CategorizedReportEntry( getSource( result ), userFriendlyTestName, group ) ); - } - - private String getSource( ITestResult result ) - { - return result.getTestClass().getName(); + String clazz = result.getTestClass().getName(); + String group = groupString( result.getMethod().getGroups(), clazz ); + reporter.testStarting( new CategorizedReportEntry( clazz, result.getName(), group ) ); } @Override public void onTestSuccess( ITestResult result ) { - ReportEntry report = new SimpleReportEntry( getSource( result ), getUserFriendlyTestName( result ) ); + ReportEntry report = new SimpleReportEntry( result.getTestClass().getName(), result.getName() ); reporter.testSucceeded( report ); } @Override public void onTestFailure( ITestResult result ) { - ReportEntry report = withException( getSource( result ), getUserFriendlyTestName( result ), - new PojoStackTraceWriter( result.getTestClass().getRealClass().getName(), + IClass clazz = result.getTestClass(); + ReportEntry report = withException( clazz.getName(), result.getName(), + new PojoStackTraceWriter( clazz.getRealClass().getName(), result.getMethod().getMethodName(), result.getThrowable() ) ); reporter.testFailed( report ); } - private static String getUserFriendlyTestName( ITestResult result ) - { - // This is consistent with the JUnit output - return result.getName() + "(" + result.getTestClass().getName() + ")"; - } - @Override public void onTestSkipped( ITestResult result ) { Throwable t = result.getThrowable(); String reason = t == null ? null : t.getMessage(); - ReportEntry report = ignored( getSource( result ), getUserFriendlyTestName( result ), reason ); + ReportEntry report = ignored( result.getTestClass().getName(), result.getName(), reason ); reporter.testSkipped( report ); } @Override public void onTestFailedButWithinSuccessPercentage( ITestResult result ) { - ReportEntry report = withException( getSource( result ), getUserFriendlyTestName( result ), - new PojoStackTraceWriter( result.getTestClass().getRealClass().getName(), + IClass clazz = result.getTestClass(); + ReportEntry report = withException( clazz.getName(), result.getName(), + new PojoStackTraceWriter( clazz.getRealClass().getName(), result.getMethod().getMethodName(), result.getThrowable() ) ); diff --git a/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportParser.java b/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportParser.java index da1b255..f6e644f 100644 --- a/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportParser.java +++ b/surefire-report-parser/src/main/java/org/apache/maven/plugins/surefire/report/SurefireReportParser.java @@ -33,11 +33,10 @@ import javax.xml.parsers.ParserConfigurationException; import org.apache.maven.plugin.surefire.log.api.ConsoleLogger; import org.apache.maven.reporting.MavenReportException; -import org.apache.maven.shared.utils.StringUtils; import org.apache.maven.shared.utils.io.DirectoryScanner; import org.xml.sax.SAXException; -import static java.util.Collections.singletonList; +import static org.apache.maven.shared.utils.StringUtils.split; /** * @@ -57,7 +56,7 @@ public final class SurefireReportParser private final ConsoleLogger consoleLogger; - private List<File> reportsDirectories; + private final List<File> reportsDirectories; public SurefireReportParser( List<File> reportsDirectories, Locale locale, ConsoleLogger consoleLogger ) { @@ -104,21 +103,6 @@ public final class SurefireReportParser return testSuites; } - protected String parseTestSuiteName( String lineString ) - { - return lineString.substring( lineString.lastIndexOf( "." ) + 1, lineString.length() ); - } - - protected String parseTestSuitePackageName( String lineString ) - { - return lineString.substring( lineString.indexOf( ":" ) + 2, lineString.lastIndexOf( "." ) ); - } - - protected String parseTestCaseName( String lineString ) - { - return lineString.substring( 0, lineString.indexOf( "(" ) ); - } - public Map<String, String> getSummary( List<ReportTestSuite> suites ) { Map<String, String> totalSummary = new HashMap<>(); @@ -164,11 +148,6 @@ public final class SurefireReportParser return totalSummary; } - public void setReportsDirectory( File reportsDirectory ) - { - reportsDirectories = singletonList( reportsDirectory ); - } - public NumberFormat getNumberFormat() { return numberFormat; @@ -238,9 +217,9 @@ public final class SurefireReportParser scanner.setBasedir( directory ); - scanner.setIncludes( StringUtils.split( includes, "," ) ); + scanner.setIncludes( split( includes, "," ) ); - scanner.setExcludes( StringUtils.split( excludes, "," ) ); + scanner.setExcludes( split( excludes, "," ) ); scanner.scan(); diff --git a/surefire-report-parser/src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportParserTest.java b/surefire-report-parser/src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportParserTest.java index 870cd92..7176c4d 100644 --- a/surefire-report-parser/src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportParserTest.java +++ b/surefire-report-parser/src/test/java/org/apache/maven/plugins/surefire/report/SurefireReportParserTest.java @@ -29,10 +29,10 @@ import java.util.List; import java.util.Map; import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger; -import org.apache.maven.reporting.MavenReportException; import junit.framework.TestCase; +import static java.util.Collections.singletonList; import static java.util.Locale.ENGLISH; /** @@ -41,23 +41,11 @@ import static java.util.Locale.ENGLISH; public class SurefireReportParserTest extends TestCase { - private SurefireReportParser report; - - /** - * {@inheritDoc} - */ - @Override - protected void setUp() - throws Exception - { - super.setUp(); - report = new SurefireReportParser( null, ENGLISH, new NullConsoleLogger() ); - } - public void testParseXMLReportFiles() - throws MavenReportException, UnsupportedEncodingException + throws Exception { - report.setReportsDirectory( getTestDir() ); + SurefireReportParser report = + new SurefireReportParser( singletonList( getTestDir() ), ENGLISH, new NullConsoleLogger() ); List<ReportTestSuite> suites = report.parseXMLReportFiles(); @@ -79,21 +67,6 @@ public class SurefireReportParserTest return new File( URLDecoder.decode( resource.getPath(), "UTF-8" ) ).getAbsoluteFile(); } - public void testParseTestSuiteName() - { - assertEquals( "CircleTest", report.parseTestSuiteName( "Battery: com.shape.CircleTest" ) ); - } - - public void testParseTestSuitePackageName() - { - assertEquals( "com.shape", report.parseTestSuitePackageName( "Battery: com.shape.CircleTest" ) ); - } - - public void testParseTestCaseName() - { - assertEquals( "testCase", report.parseTestCaseName( "testCase(com.shape.CircleTest)" ) ); - } - public void testGetSummary() throws Exception { @@ -117,6 +90,8 @@ public class SurefireReportParserTest suites.add( tSuite2 ); + SurefireReportParser report = new SurefireReportParser( null, ENGLISH, new NullConsoleLogger() ); + Map<String, String> testMap = report.getSummary( suites ); assertEquals( 20, Integer.parseInt( testMap.get( "totalErrors" ) ) ); @@ -156,6 +131,8 @@ public class SurefireReportParserTest suites.add( tSuite3 ); + SurefireReportParser report = new SurefireReportParser( null, ENGLISH, new NullConsoleLogger() ); + Map<String, List<ReportTestSuite>> groupMap = report.getSuitesGroupByPackage( suites ); assertEquals( 2, groupMap.size() ); @@ -170,6 +147,7 @@ public class SurefireReportParserTest public void testComputePercentage() throws Exception { + SurefireReportParser report = new SurefireReportParser( null, ENGLISH, new NullConsoleLogger() ); NumberFormat numberFormat = report.getNumberFormat(); assertEquals( 70.00f, numberFormat.parse( report.computePercentage( 100, 20, 10, 0 ) ).floatValue(), 0 ); @@ -211,6 +189,8 @@ public class SurefireReportParserTest suites.add( tSuite2 ); + SurefireReportParser report = new SurefireReportParser( null, ENGLISH, new NullConsoleLogger() ); + List<ReportTestCase> failures = report.getFailureDetails( suites ); assertEquals( 2, failures.size() );
