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