View Javadoc
1   package org.apache.maven.plugin.surefire;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.List;
26  import java.util.Map;
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.plugin.MojoExecutionException;
29  import org.apache.maven.plugin.MojoFailureException;
30  import org.apache.maven.plugins.annotations.LifecyclePhase;
31  import org.apache.maven.plugins.annotations.Mojo;
32  import org.apache.maven.plugins.annotations.Parameter;
33  import org.apache.maven.plugins.annotations.ResolutionScope;
34  import org.apache.maven.surefire.suite.RunResult;
35  
36  import static org.apache.maven.plugin.surefire.SurefireHelper.reportExecution;
37  
38  /**
39   * Run tests using Surefire.
40   *
41   * @author Jason van Zyl
42   */
43  @Mojo( name = "test", defaultPhase = LifecyclePhase.TEST, threadSafe = true,
44         requiresDependencyResolution = ResolutionScope.TEST )
45  public class SurefirePlugin
46      extends AbstractSurefireMojo
47      implements SurefireReportParameters
48  {
49  
50      /**
51       * The directory containing generated classes of the project being tested. This will be included after the test
52       * classes in the test classpath.
53       */
54      @Parameter( defaultValue = "${project.build.outputDirectory}" )
55      private File classesDirectory;
56  
57      /**
58       * Set this to "true" to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
59       * occasion.
60       */
61      @Parameter( property = "maven.test.failure.ignore", defaultValue = "false" )
62      private boolean testFailureIgnore;
63  
64      /**
65       * Base directory where all reports are written to.
66       */
67      @Parameter( defaultValue = "${project.build.directory}/surefire-reports" )
68      private File reportsDirectory;
69  
70      @SuppressWarnings( "checkstyle:linelength" )
71      /**
72       * Specify this parameter to run individual tests by file name, overriding the parameter {@code includes} and
73       * {@code excludes}. Each pattern you specify here will be used to create an include pattern formatted like
74       * <code>**{@literal /}${test}.java</code>, so you can just type {@code -Dtest=MyTest} to run a single test called
75       * "foo/MyTest.java". The test patterns prefixed with a <em>!</em> will be excluded.
76       * <br>
77       * This parameter overrides the parameter {@code includes}, {@code excludes}, and the TestNG parameter
78       * {@code suiteXmlFiles}.
79       * <br>
80       * Since 2.7.3, you can execute a limited number of methods in the test by adding <i>#myMethod</i> or
81       * <i>#my*ethod</i>. For example, {@code -Dtest=MyTest#myMethod}. This is supported for junit 4.x and TestNg.<br>
82       * <br>
83       * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
84       * <pre><code>"-Dtest=???Test, !Unstable*, pkg{@literal /}**{@literal /}Ci*leTest.java, *Test#test*One+testTwo?????, #fast*+slowTest"</code></pre>
85       * or e.g.
86       * <pre><code>"-Dtest=Basic*, !%regex[.*.Unstable.*], !%regex[.*.MyTest.class#one.*|two.*], %regex[#fast.*|slow.*]"</code></pre>
87       * <br>
88       * The Parameterized JUnit runner {@code describes} test methods using an index in brackets, so the non-regex
89       * method pattern would become: {@code #testMethod[*]}.
90       * If using <code>@Parameters(name="{index}: fib({0})={1}")</code> and selecting the index e.g. 5 in pattern, the
91       * non-regex method pattern would become {@code #testMethod[5:*]}.
92       */
93      @Parameter( property = "test" )
94      private String test;
95  
96      /**
97       * Option to print summary of test suites or just print the test cases that have errors.
98       */
99      @Parameter( property = "surefire.printSummary", defaultValue = "true" )
100     private boolean printSummary;
101 
102     /**
103      * Selects the formatting for the test report to be generated. Can be set as "brief" or "plain".
104      * Only applies to the output format of the output files  (target/surefire-reports/testName.txt)
105      */
106     @Parameter( property = "surefire.reportFormat", defaultValue = "brief" )
107     private String reportFormat;
108 
109     /**
110      * Option to generate a file test report or just output the test report to the console.
111      */
112     @Parameter( property = "surefire.useFile", defaultValue = "true" )
113     private boolean useFile;
114 
115     /**
116      * Set this to "true" to cause a failure if none of the tests specified in -Dtest=... are run. Defaults to
117      * "true".
118      *
119      * @since 2.12
120      */
121     @Parameter( property = "surefire.failIfNoSpecifiedTests" )
122     private Boolean failIfNoSpecifiedTests;
123 
124     /**
125      * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
126      * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
127      * arbitrary debuggability options (without overwriting the other options specified through the {@code argLine}
128      * parameter).
129      *
130      * @since 2.4
131      */
132     @Parameter( property = "maven.surefire.debug" )
133     private String debugForkedProcess;
134 
135     /**
136      * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
137      * timing out.
138      *
139      * @since 2.4
140      */
141     @Parameter( property = "surefire.timeout" )
142     private int forkedProcessTimeoutInSeconds;
143 
144     /**
145      * Forked process is normally terminated without any significant delay after given tests have completed.
146      * If the particular tests started non-daemon Thread(s), the process hangs instead of been properly terminated
147      * by {@code System.exit()}. Use this parameter in order to determine the timeout of terminating the process.
148      * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/examples/shutdown.html">see the documentation:
149      * http://maven.apache.org/surefire/maven-surefire-plugin/examples/shutdown.html</a>;
150      * Turns to default fallback value of 30 seconds if negative integer.
151      *
152      * @since 2.20
153      */
154     @Parameter( property = "surefire.exitTimeout", defaultValue = "30" )
155     private int forkedProcessExitTimeoutInSeconds;
156 
157     /**
158      * Stop executing queued parallel JUnit tests after a certain number of seconds.
159      * <br>
160      * Example values: "3.5", "4"<br>
161      * <br>
162      * If set to 0, wait forever, never timing out.
163      * Makes sense with specified {@code parallel} different from "none".
164      *
165      * @since 2.16
166      */
167     @Parameter( property = "surefire.parallel.timeout" )
168     private double parallelTestsTimeoutInSeconds;
169 
170     /**
171      * Stop executing queued parallel JUnit tests
172      * and {@code interrupt} currently running tests after a certain number of seconds.
173      * <br>
174      * Example values: "3.5", "4"<br>
175      * <br>
176      * If set to 0, wait forever, never timing out.
177      * Makes sense with specified {@code parallel} different from "none".
178      *
179      * @since 2.16
180      */
181     @Parameter( property = "surefire.parallel.forcedTimeout" )
182     private double parallelTestsTimeoutForcedInSeconds;
183 
184     @SuppressWarnings( "checkstyle:linelength" )
185     /**
186      * A list of &lt;include&gt; elements specifying the tests (by pattern) that should be included in testing. When not
187      * specified and when the {@code test} parameter is not specified, the default includes will be
188      * <pre><code>
189      * {@literal <includes>}
190      *     {@literal <include>}**{@literal /}Test*.java{@literal </include>}
191      *     {@literal <include>}**{@literal /}*Test.java{@literal </include>}
192      *     {@literal <include>}**{@literal /}*Tests.java{@literal </include>}
193      *     {@literal <include>}**{@literal /}*TestCase.java{@literal </include>}
194      * {@literal </includes>}
195      * </code></pre>
196      * Each include item may also contain a comma-separated sub-list of items, which will be treated as multiple
197      * &nbsp;&lt;include&gt; entries.<br>
198      * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
199      * <pre><code>
200      *
201      * </code></pre>
202      * {@literal <include>}%regex[.*[Cat|Dog].*], Basic????, !Unstable*{@literal </include>}
203      * {@literal <include>}%regex[.*[Cat|Dog].*], !%regex[pkg.*Slow.*.class], pkg{@literal /}**{@literal /}*Fast*.java{@literal </include>}
204      * <br>
205      * This parameter is ignored if the TestNG {@code suiteXmlFiles} parameter is specified.<br>
206      * <br>
207      * <b>Notice that</b> these values are relative to the directory containing generated test classes of the project
208      * being tested. This directory is declared by the parameter {@code testClassesDirectory} which defaults
209      * to the POM property {@code ${project.build.testOutputDirectory}}, typically
210      * <code>{@literal src/test/java}</code> unless overridden.
211      */
212     @Parameter
213     private List<String> includes;
214 
215     /**
216      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
217      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
218      * ClassLoader.
219      *
220      * @since 2.3
221      */
222     @Parameter( property = "surefire.useSystemClassLoader", defaultValue = "true" )
223     private boolean useSystemClassLoader;
224 
225     /**
226      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
227      * launch your tests with a plain old Java classpath. (See the
228      * <a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html">
229      *     http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html</a>;
230      * for a more detailed explanation of manifest-only JARs and their benefits.)
231      * <br>
232      * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
233      *
234      * @since 2.4.3
235      */
236     @Parameter( property = "surefire.useManifestOnlyJar", defaultValue = "true" )
237     private boolean useManifestOnlyJar;
238 
239     /**
240      * The character encoding scheme to be applied while generating test report
241      * files (see target/surefire-reports/yourTestName.txt).
242      * The report output files (*-out.txt) are still encoded with JVM's encoding used in standard out/err pipes.
243      *
244      * @since 3.0.0-M1
245      */
246     @Parameter( property = "surefire.encoding", defaultValue = "${project.reporting.outputEncoding}" )
247     private String encoding;
248 
249     /**
250      * (JUnit 4+ providers)
251      * The number of times each failing test will be rerun. If set larger than 0, rerun failing tests immediately after
252      * they fail. If a failing test passes in any of those reruns, it will be marked as pass and reported as a "flake".
253      * However, all the failing attempts will be recorded.
254      */
255     @Parameter( property = "surefire.rerunFailingTestsCount", defaultValue = "0" )
256     private int rerunFailingTestsCount;
257 
258     /**
259      * (TestNG) List of &lt;suiteXmlFile&gt; elements specifying TestNG suite xml file locations. Note that
260      * {@code suiteXmlFiles} is incompatible with several other parameters of this plugin, like
261      * {@code includes} and {@code excludes}.<br>
262      * This parameter is ignored if the {@code test} parameter is specified (allowing you to run a single test
263      * instead of an entire suite).
264      *
265      * @since 2.2
266      */
267     @Parameter( property = "surefire.suiteXmlFiles" )
268     private File[] suiteXmlFiles;
269 
270     /**
271      * Defines the order the tests will be run in. Supported values are {@code alphabetical},
272      * {@code reversealphabetical}, {@code random}, {@code hourly} (alphabetical on even hours, reverse alphabetical
273      * on odd hours), {@code failedfirst}, {@code balanced} and {@code filesystem}.
274      * <br>
275      * <br>
276      * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
277      * multi-module build.
278      * <br>
279      * <br>
280      * Failed first will run tests that failed on previous run first, as well as new tests for this run.
281      * <br>
282      * <br>
283      * Balanced is only relevant with parallel=classes, and will try to optimize the run-order of the tests reducing the
284      * overall execution time. Initially a statistics file is created and every next test run will reorder classes.
285      * <br>
286      * <br>
287      * Note that the statistics are stored in a file named <b>.surefire-XXXXXXXXX</b> beside <i>pom.xml</i> and
288      * should not be checked into version control. The "XXXXX" is the SHA1 checksum of the entire surefire
289      * configuration, so different configurations will have different statistics files, meaning if you change any
290      * configuration settings you will re-run once before new statistics data can be established.
291      *
292      * @since 2.7
293      */
294     @Parameter( property = "surefire.runOrder", defaultValue = "filesystem" )
295     private String runOrder;
296 
297     /**
298      * A file containing include patterns. Blank lines, or lines starting with # are ignored. If {@code includes} are
299      * also specified, these patterns are appended. Example with path, simple and regex includes:
300      * <pre><code>
301      * *{@literal /}test{@literal /}*
302      * **{@literal /}NotIncludedByDefault.java
303      * %regex[.*Test.*|.*Not.*]
304      * </code></pre>
305      */
306     @Parameter( property = "surefire.includesFile" )
307     private File includesFile;
308 
309     /**
310      * A file containing exclude patterns. Blank lines, or lines starting with # are ignored. If {@code excludes} are
311      * also specified, these patterns are appended. Example with path, simple and regex excludes:<br>
312      * <pre><code>
313      * *{@literal /}test{@literal /}*
314      * **{@literal /}DontRunTest.*
315      * %regex[.*Test.*|.*Not.*]
316      * </code></pre>
317      */
318     @Parameter( property = "surefire.excludesFile" )
319     private File excludesFile;
320 
321     /**
322      * Set to error/failure count in order to skip remaining tests.
323      * Due to race conditions in parallel/forked execution this may not be fully guaranteed.<br>
324      * Enable with system property {@code -Dsurefire.skipAfterFailureCount=1} or any number greater than zero.
325      * Defaults to "0".<br>
326      * See the prerequisites and limitations in documentation:<br>
327      * <a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/skip-after-failure.html">
328      *     http://maven.apache.org/plugins/maven-surefire-plugin/examples/skip-after-failure.html</a>;
329      *
330      * @since 2.19
331      */
332     @Parameter( property = "surefire.skipAfterFailureCount", defaultValue = "0" )
333     private int skipAfterFailureCount;
334 
335     /**
336      * After the plugin process is shutdown by sending <i>SIGTERM signal (CTRL+C)</i>, <i>SHUTDOWN command</i> is
337      * received by every forked JVM.
338      * <br>
339      * By default ({@code shutdown=testset}) forked JVM would not continue with new test which means that
340      * the current test may still continue to run.
341      * <br>
342      * The parameter can be configured with other two values {@code exit} and {@code kill}.
343      * <br>
344      * Using {@code exit} forked JVM executes {@code System.exit(1)} after the plugin process has received
345      * <i>SIGTERM signal</i>.
346      * <br>
347      * Using {@code kill} the JVM executes {@code Runtime.halt(1)} and kills itself.
348      *
349      * @since 2.19
350      */
351     @Parameter( property = "surefire.shutdown", defaultValue = "testset" )
352     private String shutdown;
353 
354     @Override
355     protected int getRerunFailingTestsCount()
356     {
357         return rerunFailingTestsCount;
358     }
359 
360     @Override
361     protected void handleSummary( RunResult summary, Exception firstForkException )
362         throws MojoExecutionException, MojoFailureException
363     {
364         reportExecution( this, summary, getConsoleLogger(), firstForkException );
365     }
366 
367     @Override
368     protected boolean isSkipExecution()
369     {
370         return isSkip() || isSkipTests() || isSkipExec();
371     }
372 
373     @Override
374     protected String getPluginName()
375     {
376         return "surefire";
377     }
378 
379     @Override
380     protected String[] getDefaultIncludes()
381     {
382         return new String[]{ "**/Test*.java", "**/*Test.java", "**/*Tests.java", "**/*TestCase.java" };
383     }
384 
385     @Override
386     protected String getReportSchemaLocation()
387     {
388         return "https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd";
389     }
390 
391     @Override
392     protected Artifact getMojoArtifact()
393     {
394         final Map<String, Artifact> pluginArtifactMap = getPluginArtifactMap();
395         return pluginArtifactMap.get( "org.apache.maven.plugins:maven-surefire-plugin" );
396     }
397     
398     // now for the implementation of the field accessors
399 
400     @Override
401     public boolean isSkipTests()
402     {
403         return skipTests;
404     }
405 
406     @Override
407     public void setSkipTests( boolean skipTests )
408     {
409         this.skipTests = skipTests;
410     }
411 
412     @Override
413     public boolean isSkipExec()
414     {
415         return skipExec;
416     }
417 
418     @Override
419     public void setSkipExec( boolean skipExec )
420     {
421         this.skipExec = skipExec;
422     }
423 
424     @Override
425     public boolean isSkip()
426     {
427         return skip;
428     }
429 
430     @Override
431     public void setSkip( boolean skip )
432     {
433         this.skip = skip;
434     }
435 
436     @Override
437     public boolean isTestFailureIgnore()
438     {
439         return testFailureIgnore;
440     }
441 
442     @Override
443     public void setTestFailureIgnore( boolean testFailureIgnore )
444     {
445         this.testFailureIgnore = testFailureIgnore;
446     }
447 
448     @Override
449     public File getBasedir()
450     {
451         return basedir;
452     }
453 
454     @Override
455     public void setBasedir( File basedir )
456     {
457         this.basedir = basedir;
458     }
459 
460     @Override
461     public File getTestClassesDirectory()
462     {
463         return testClassesDirectory;
464     }
465 
466     @Override
467     public void setTestClassesDirectory( File testClassesDirectory )
468     {
469         this.testClassesDirectory = testClassesDirectory;
470     }
471 
472     @Override
473     public File getClassesDirectory()
474     {
475         return classesDirectory;
476     }
477 
478     @Override
479     public void setClassesDirectory( File classesDirectory )
480     {
481         this.classesDirectory = classesDirectory;
482     }
483 
484     @Override
485     public File getReportsDirectory()
486     {
487         return reportsDirectory;
488     }
489 
490     @Override
491     public void setReportsDirectory( File reportsDirectory )
492     {
493         this.reportsDirectory = reportsDirectory;
494     }
495 
496     @Override
497     public String getTest()
498     {
499         return test;
500     }
501 
502     @Override
503     public boolean isUseSystemClassLoader()
504     {
505         return useSystemClassLoader;
506     }
507 
508     @Override
509     public void setUseSystemClassLoader( boolean useSystemClassLoader )
510     {
511         this.useSystemClassLoader = useSystemClassLoader;
512     }
513 
514     @Override
515     public boolean isUseManifestOnlyJar()
516     {
517         return useManifestOnlyJar;
518     }
519 
520     @Override
521     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
522     {
523         this.useManifestOnlyJar = useManifestOnlyJar;
524     }
525 
526     @Override
527     public String getEncoding()
528     {
529         return encoding;
530     }
531 
532     @Override
533     public void setEncoding( String encoding )
534     {
535         this.encoding = encoding;
536     }
537 
538     @Override
539     public Boolean getFailIfNoSpecifiedTests()
540     {
541         return failIfNoSpecifiedTests;
542     }
543 
544     @Override
545     public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
546     {
547         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
548     }
549 
550     @Override
551     public int getSkipAfterFailureCount()
552     {
553         return skipAfterFailureCount;
554     }
555 
556     @Override
557     public String getShutdown()
558     {
559         return shutdown;
560     }
561 
562     @Override
563     public boolean isPrintSummary()
564     {
565         return printSummary;
566     }
567 
568     @Override
569     public void setPrintSummary( boolean printSummary )
570     {
571         this.printSummary = printSummary;
572     }
573 
574     @Override
575     public String getReportFormat()
576     {
577         return reportFormat;
578     }
579 
580     @Override
581     public void setReportFormat( String reportFormat )
582     {
583         this.reportFormat = reportFormat;
584     }
585 
586     @Override
587     public boolean isUseFile()
588     {
589         return useFile;
590     }
591 
592     @Override
593     public void setUseFile( boolean useFile )
594     {
595         this.useFile = useFile;
596     }
597 
598     @Override
599     public String getDebugForkedProcess()
600     {
601         return debugForkedProcess;
602     }
603 
604     @Override
605     public void setDebugForkedProcess( String debugForkedProcess )
606     {
607         this.debugForkedProcess = debugForkedProcess;
608     }
609 
610     @Override
611     public int getForkedProcessTimeoutInSeconds()
612     {
613         return forkedProcessTimeoutInSeconds;
614     }
615 
616     @Override
617     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
618     {
619         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
620     }
621 
622     @Override
623     public int getForkedProcessExitTimeoutInSeconds()
624     {
625         return forkedProcessExitTimeoutInSeconds;
626     }
627 
628     @Override
629     public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
630     {
631         this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
632     }
633 
634     @Override
635     public double getParallelTestsTimeoutInSeconds()
636     {
637         return parallelTestsTimeoutInSeconds;
638     }
639 
640     @Override
641     public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
642     {
643         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
644     }
645 
646     @Override
647     public double getParallelTestsTimeoutForcedInSeconds()
648     {
649         return parallelTestsTimeoutForcedInSeconds;
650     }
651 
652     @Override
653     public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
654     {
655         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
656     }
657 
658     @Override
659     public void setTest( String test )
660     {
661         this.test = test;
662     }
663 
664     @Override
665     public List<String> getIncludes()
666     {
667         return includes;
668     }
669 
670     @Override
671     public void setIncludes( List<String> includes )
672     {
673         this.includes = includes;
674     }
675 
676     @Override
677     public File[] getSuiteXmlFiles()
678     {
679         return suiteXmlFiles.clone();
680     }
681 
682     @Override
683     @SuppressWarnings( "UnusedDeclaration" )
684     public void setSuiteXmlFiles( File[] suiteXmlFiles )
685     {
686         this.suiteXmlFiles = suiteXmlFiles.clone();
687     }
688 
689     @Override
690     public String getRunOrder()
691     {
692         return runOrder;
693     }
694 
695     @Override
696     @SuppressWarnings( "UnusedDeclaration" )
697     public void setRunOrder( String runOrder )
698     {
699         this.runOrder = runOrder;
700     }
701 
702     @Override
703     public File getIncludesFile()
704     {
705         return includesFile;
706     }
707 
708     @Override
709     public File getExcludesFile()
710     {
711         return excludesFile;
712     }
713 
714     @Override
715     protected final List<File> suiteXmlFiles()
716     {
717         return hasSuiteXmlFiles() ? Arrays.asList( suiteXmlFiles ) : Collections.<File>emptyList();
718     }
719 
720     @Override
721     protected final boolean hasSuiteXmlFiles()
722     {
723         return suiteXmlFiles != null && suiteXmlFiles.length != 0;
724     }
725 }