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      * (JUnit 4+ providers)
241      * The number of times each failing test will be rerun. If set larger than 0, rerun failing tests immediately after
242      * they fail. If a failing test passes in any of those reruns, it will be marked as pass and reported as a "flake".
243      * However, all the failing attempts will be recorded.
244      */
245     @Parameter( property = "surefire.rerunFailingTestsCount", defaultValue = "0" )
246     private int rerunFailingTestsCount;
247 
248     /**
249      * (TestNG) List of &lt;suiteXmlFile&gt; elements specifying TestNG suite xml file locations. Note that
250      * {@code suiteXmlFiles} is incompatible with several other parameters of this plugin, like
251      * {@code includes} and {@code excludes}.<br>
252      * This parameter is ignored if the {@code test} parameter is specified (allowing you to run a single test
253      * instead of an entire suite).
254      *
255      * @since 2.2
256      */
257     @Parameter( property = "surefire.suiteXmlFiles" )
258     private File[] suiteXmlFiles;
259 
260     /**
261      * Defines the order the tests will be run in. Supported values are {@code alphabetical},
262      * {@code reversealphabetical}, {@code random}, {@code hourly} (alphabetical on even hours, reverse alphabetical
263      * on odd hours), {@code failedfirst}, {@code balanced} and {@code filesystem}.
264      * <br>
265      * <br>
266      * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
267      * multi-module build.
268      * <br>
269      * <br>
270      * Failed first will run tests that failed on previous run first, as well as new tests for this run.
271      * <br>
272      * <br>
273      * Balanced is only relevant with parallel=classes, and will try to optimize the run-order of the tests reducing the
274      * overall execution time. Initially a statistics file is created and every next test run will reorder classes.
275      * <br>
276      * <br>
277      * Note that the statistics are stored in a file named <b>.surefire-XXXXXXXXX</b> beside <i>pom.xml</i> and
278      * should not be checked into version control. The "XXXXX" is the SHA1 checksum of the entire surefire
279      * configuration, so different configurations will have different statistics files, meaning if you change any
280      * configuration settings you will re-run once before new statistics data can be established.
281      *
282      * @since 2.7
283      */
284     @Parameter( property = "surefire.runOrder", defaultValue = "filesystem" )
285     private String runOrder;
286 
287     /**
288      * A file containing include patterns. Blank lines, or lines starting with # are ignored. If {@code includes} are
289      * also specified, these patterns are appended. Example with path, simple and regex includes:
290      * <pre><code>
291      * *{@literal /}test{@literal /}*
292      * **{@literal /}NotIncludedByDefault.java
293      * %regex[.*Test.*|.*Not.*]
294      * </code></pre>
295      */
296     @Parameter( property = "surefire.includesFile" )
297     private File includesFile;
298 
299     /**
300      * A file containing exclude patterns. Blank lines, or lines starting with # are ignored. If {@code excludes} are
301      * also specified, these patterns are appended. Example with path, simple and regex excludes:<br>
302      * <pre><code>
303      * *{@literal /}test{@literal /}*
304      * **{@literal /}DontRunTest.*
305      * %regex[.*Test.*|.*Not.*]
306      * </code></pre>
307      */
308     @Parameter( property = "surefire.excludesFile" )
309     private File excludesFile;
310 
311     /**
312      * Set to error/failure count in order to skip remaining tests.
313      * Due to race conditions in parallel/forked execution this may not be fully guaranteed.<br>
314      * Enable with system property {@code -Dsurefire.skipAfterFailureCount=1} or any number greater than zero.
315      * Defaults to "0".<br>
316      * See the prerequisites and limitations in documentation:<br>
317      * <a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/skip-after-failure.html">
318      *     http://maven.apache.org/plugins/maven-surefire-plugin/examples/skip-after-failure.html</a>;
319      *
320      * @since 2.19
321      */
322     @Parameter( property = "surefire.skipAfterFailureCount", defaultValue = "0" )
323     private int skipAfterFailureCount;
324 
325     /**
326      * After the plugin process is shutdown by sending <i>SIGTERM signal (CTRL+C)</i>, <i>SHUTDOWN command</i> is
327      * received by every forked JVM.
328      * <br>
329      * By default ({@code shutdown=testset}) forked JVM would not continue with new test which means that
330      * the current test may still continue to run.
331      * <br>
332      * The parameter can be configured with other two values {@code exit} and {@code kill}.
333      * <br>
334      * Using {@code exit} forked JVM executes {@code System.exit(1)} after the plugin process has received
335      * <i>SIGTERM signal</i>.
336      * <br>
337      * Using {@code kill} the JVM executes {@code Runtime.halt(1)} and kills itself.
338      *
339      * @since 2.19
340      */
341     @Parameter( property = "surefire.shutdown", defaultValue = "testset" )
342     private String shutdown;
343 
344     @Override
345     protected int getRerunFailingTestsCount()
346     {
347         return rerunFailingTestsCount;
348     }
349 
350     @Override
351     protected void handleSummary( RunResult summary, Exception firstForkException )
352         throws MojoExecutionException, MojoFailureException
353     {
354         reportExecution( this, summary, getConsoleLogger(), firstForkException );
355     }
356 
357     @Override
358     protected boolean isSkipExecution()
359     {
360         return isSkip() || isSkipTests() || isSkipExec();
361     }
362 
363     @Override
364     protected String getPluginName()
365     {
366         return "surefire";
367     }
368 
369     @Override
370     protected String[] getDefaultIncludes()
371     {
372         return new String[]{ "**/Test*.java", "**/*Test.java", "**/*Tests.java", "**/*TestCase.java" };
373     }
374 
375     @Override
376     protected String getReportSchemaLocation()
377     {
378         return "https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd";
379     }
380 
381     @Override
382     protected Artifact getMojoArtifact()
383     {
384         final Map<String, Artifact> pluginArtifactMap = getPluginArtifactMap();
385         return pluginArtifactMap.get( "org.apache.maven.plugins:maven-surefire-plugin" );
386     }
387     
388     // now for the implementation of the field accessors
389 
390     @Override
391     public boolean isSkipTests()
392     {
393         return skipTests;
394     }
395 
396     @Override
397     public void setSkipTests( boolean skipTests )
398     {
399         this.skipTests = skipTests;
400     }
401 
402     @Override
403     public boolean isSkipExec()
404     {
405         return skipExec;
406     }
407 
408     @Override
409     public void setSkipExec( boolean skipExec )
410     {
411         this.skipExec = skipExec;
412     }
413 
414     @Override
415     public boolean isSkip()
416     {
417         return skip;
418     }
419 
420     @Override
421     public void setSkip( boolean skip )
422     {
423         this.skip = skip;
424     }
425 
426     @Override
427     public boolean isTestFailureIgnore()
428     {
429         return testFailureIgnore;
430     }
431 
432     @Override
433     public void setTestFailureIgnore( boolean testFailureIgnore )
434     {
435         this.testFailureIgnore = testFailureIgnore;
436     }
437 
438     @Override
439     public File getBasedir()
440     {
441         return basedir;
442     }
443 
444     @Override
445     public void setBasedir( File basedir )
446     {
447         this.basedir = basedir;
448     }
449 
450     @Override
451     public File getTestClassesDirectory()
452     {
453         return testClassesDirectory;
454     }
455 
456     @Override
457     public void setTestClassesDirectory( File testClassesDirectory )
458     {
459         this.testClassesDirectory = testClassesDirectory;
460     }
461 
462     @Override
463     public File getClassesDirectory()
464     {
465         return classesDirectory;
466     }
467 
468     @Override
469     public void setClassesDirectory( File classesDirectory )
470     {
471         this.classesDirectory = classesDirectory;
472     }
473 
474     @Override
475     public File getReportsDirectory()
476     {
477         return reportsDirectory;
478     }
479 
480     @Override
481     public void setReportsDirectory( File reportsDirectory )
482     {
483         this.reportsDirectory = reportsDirectory;
484     }
485 
486     @Override
487     public String getTest()
488     {
489         return test;
490     }
491 
492     @Override
493     public boolean isUseSystemClassLoader()
494     {
495         return useSystemClassLoader;
496     }
497 
498     @Override
499     public void setUseSystemClassLoader( boolean useSystemClassLoader )
500     {
501         this.useSystemClassLoader = useSystemClassLoader;
502     }
503 
504     @Override
505     public boolean isUseManifestOnlyJar()
506     {
507         return useManifestOnlyJar;
508     }
509 
510     @Override
511     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
512     {
513         this.useManifestOnlyJar = useManifestOnlyJar;
514     }
515 
516     @Override
517     public Boolean getFailIfNoSpecifiedTests()
518     {
519         return failIfNoSpecifiedTests;
520     }
521 
522     @Override
523     public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
524     {
525         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
526     }
527 
528     @Override
529     public int getSkipAfterFailureCount()
530     {
531         return skipAfterFailureCount;
532     }
533 
534     @Override
535     public String getShutdown()
536     {
537         return shutdown;
538     }
539 
540     @Override
541     public boolean isPrintSummary()
542     {
543         return printSummary;
544     }
545 
546     @Override
547     public void setPrintSummary( boolean printSummary )
548     {
549         this.printSummary = printSummary;
550     }
551 
552     @Override
553     public String getReportFormat()
554     {
555         return reportFormat;
556     }
557 
558     @Override
559     public void setReportFormat( String reportFormat )
560     {
561         this.reportFormat = reportFormat;
562     }
563 
564     @Override
565     public boolean isUseFile()
566     {
567         return useFile;
568     }
569 
570     @Override
571     public void setUseFile( boolean useFile )
572     {
573         this.useFile = useFile;
574     }
575 
576     @Override
577     public String getDebugForkedProcess()
578     {
579         return debugForkedProcess;
580     }
581 
582     @Override
583     public void setDebugForkedProcess( String debugForkedProcess )
584     {
585         this.debugForkedProcess = debugForkedProcess;
586     }
587 
588     @Override
589     public int getForkedProcessTimeoutInSeconds()
590     {
591         return forkedProcessTimeoutInSeconds;
592     }
593 
594     @Override
595     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
596     {
597         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
598     }
599 
600     @Override
601     public int getForkedProcessExitTimeoutInSeconds()
602     {
603         return forkedProcessExitTimeoutInSeconds;
604     }
605 
606     @Override
607     public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
608     {
609         this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
610     }
611 
612     @Override
613     public double getParallelTestsTimeoutInSeconds()
614     {
615         return parallelTestsTimeoutInSeconds;
616     }
617 
618     @Override
619     public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
620     {
621         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
622     }
623 
624     @Override
625     public double getParallelTestsTimeoutForcedInSeconds()
626     {
627         return parallelTestsTimeoutForcedInSeconds;
628     }
629 
630     @Override
631     public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
632     {
633         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
634     }
635 
636     @Override
637     public void setTest( String test )
638     {
639         this.test = test;
640     }
641 
642     @Override
643     public List<String> getIncludes()
644     {
645         return includes;
646     }
647 
648     @Override
649     public void setIncludes( List<String> includes )
650     {
651         this.includes = includes;
652     }
653 
654     @Override
655     public File[] getSuiteXmlFiles()
656     {
657         return suiteXmlFiles.clone();
658     }
659 
660     @Override
661     @SuppressWarnings( "UnusedDeclaration" )
662     public void setSuiteXmlFiles( File[] suiteXmlFiles )
663     {
664         this.suiteXmlFiles = suiteXmlFiles.clone();
665     }
666 
667     @Override
668     public String getRunOrder()
669     {
670         return runOrder;
671     }
672 
673     @Override
674     @SuppressWarnings( "UnusedDeclaration" )
675     public void setRunOrder( String runOrder )
676     {
677         this.runOrder = runOrder;
678     }
679 
680     @Override
681     public File getIncludesFile()
682     {
683         return includesFile;
684     }
685 
686     @Override
687     public File getExcludesFile()
688     {
689         return excludesFile;
690     }
691 
692     @Override
693     protected final List<File> suiteXmlFiles()
694     {
695         return hasSuiteXmlFiles() ? Arrays.asList( suiteXmlFiles ) : Collections.<File>emptyList();
696     }
697 
698     @Override
699     protected final boolean hasSuiteXmlFiles()
700     {
701         return suiteXmlFiles != null && suiteXmlFiles.length != 0;
702     }
703 }