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.List;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugins.annotations.LifecyclePhase;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.plugins.annotations.ResolutionScope;
30  import org.apache.maven.surefire.suite.RunResult;
31  import org.apache.maven.surefire.util.NestedCheckedException;
32  import org.apache.maven.surefire.util.internal.StringUtils;
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       * Set this to "true" to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
49       * occasion.
50       */
51      @Parameter( property = "maven.test.failure.ignore", defaultValue = "false" )
52      private boolean testFailureIgnore;
53  
54      /**
55       * Base directory where all reports are written to.
56       */
57      @Parameter( defaultValue = "${project.build.directory}/surefire-reports" )
58      private File reportsDirectory;
59  
60      /**
61       * Specify this parameter to run individual tests by file name, overriding the <code>includes/excludes</code>
62       * parameters. Each pattern you specify here will be used to create an include pattern formatted like
63       * <code>**&#47;${test}.java</code>, so you can just type "-Dtest=MyTest" to run a single test called
64       * "foo/MyTest.java". The test patterns prefixed with a <code>!</code> will be excluded.<br/>
65       * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG <code>suiteXmlFiles</code>
66       * parameter.
67       * <p/>
68       * Since 2.7.3, you can execute a limited number of methods in the test by adding #myMethod or #my*ethod. For example,
69       * "-Dtest=MyTest#myMethod".  This is supported for junit 4.x and testNg.
70       */
71      @Parameter( property = "test" )
72      private String test;
73  
74      /**
75       * Option to print summary of test suites or just print the test cases that have errors.
76       */
77      @Parameter( property = "surefire.printSummary", defaultValue = "true" )
78      private boolean printSummary;
79  
80      /**
81       * Selects the formatting for the test report to be generated. Can be set as "brief" or "plain".
82       * Only applies to the output format of the output files  (target/surefire-reports/testName.txt)
83       */
84      @Parameter( property = "surefire.reportFormat", defaultValue = "brief" )
85      private String reportFormat;
86  
87      /**
88       * Option to generate a file test report or just output the test report to the console.
89       */
90      @Parameter( property = "surefire.useFile", defaultValue = "true" )
91      private boolean useFile;
92  
93  
94      /**
95       * Set this to "true" to cause a failure if the none of the tests specified in -Dtest=... are run. Defaults to
96       * "true".
97       *
98       * @since 2.12
99       */
100     @Parameter( property = "surefire.failIfNoSpecifiedTests" )
101     private Boolean failIfNoSpecifiedTests;
102 
103     /**
104      * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
105      * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
106      * arbitrary debuggability options (without overwriting the other options specified through the <code>argLine</code>
107      * parameter).
108      *
109      * @since 2.4
110      */
111     @Parameter( property = "maven.surefire.debug" )
112     private String debugForkedProcess;
113 
114     /**
115      * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
116      * timing out.
117      *
118      * @since 2.4
119      */
120     @Parameter( property = "surefire.timeout" )
121     private int forkedProcessTimeoutInSeconds;
122 
123     /**
124      * Stop executing queued parallel JUnit tests after a certain number of seconds.
125      * If set to 0, wait forever, never timing out.
126      * Makes sense with specified <code>parallel</code> different from "none".
127      *
128      * @since 2.16
129      */
130     @Parameter( property = "surefire.parallel.timeout" )
131     private int parallelTestsTimeoutInSeconds;
132 
133     /**
134      * Stop executing queued parallel JUnit tests
135      * and <em>interrupt</em> currently running tests after a certain number of seconds.
136      * If set to 0, wait forever, never timing out.
137      * Makes sense with specified <code>parallel</code> different from "none".
138      *
139      * @since 2.16
140      */
141     @Parameter( property = "surefire.parallel.forcedTimeout" )
142     private int parallelTestsTimeoutForcedInSeconds;
143     
144     /**
145      * A list of &lt;include> elements specifying the tests (by pattern) that should be included in testing. When not
146      * specified and when the <code>test</code> parameter is not specified, the default includes will be <code><br/>
147      * &lt;includes><br/>
148      * &nbsp;&lt;include>**&#47;Test*.java&lt;/include><br/>
149      * &nbsp;&lt;include>**&#47;*Test.java&lt;/include><br/>
150      * &nbsp;&lt;include>**&#47;*TestCase.java&lt;/include><br/>
151      * &lt;/includes><br/>
152      * </code>
153      * <p/>
154      * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple
155      * &nbsp;&lt;include> entries.<br/>
156      * <p/>
157      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
158      */
159     @Parameter
160     private List<String> includes;
161 
162     /**
163      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
164      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
165      * classloader.
166      *
167      * @since 2.3
168      */
169     @Parameter( property = "surefire.useSystemClassLoader", defaultValue = "true" )
170     private boolean useSystemClassLoader;
171 
172     /**
173      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
174      * launch your tests with a plain old Java classpath. (See
175      * http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html for a more detailed explanation
176      * of manifest-only JARs and their benefits.)
177      * <p/>
178      * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
179      *
180      * @since 2.4.3
181      */
182     @Parameter( property = "surefire.useManifestOnlyJar", defaultValue = "true" )
183     private boolean useManifestOnlyJar;
184 
185     protected void handleSummary( RunResult summary, NestedCheckedException firstForkException )
186         throws MojoExecutionException, MojoFailureException
187     {
188         assertNoException( firstForkException );
189 
190         SurefireHelper.reportExecution( this, summary, getLog() );
191     }
192 
193     private void assertNoException( NestedCheckedException firstForkException )
194         throws MojoFailureException
195     {
196         if ( firstForkException != null )
197         {
198             throw new MojoFailureException( firstForkException.getMessage(), firstForkException );
199         }
200     }
201 
202     private void assertNoFailureOrTimeout( NestedCheckedException summary )
203         throws MojoFailureException
204     {
205         if ( summary != null )
206         {
207             throw new MojoFailureException( "Failure or timeout" );
208         }
209     }
210 
211     protected boolean isSkipExecution()
212     {
213         return isSkip() || isSkipTests() || isSkipExec();
214     }
215 
216     protected String getPluginName()
217     {
218         return "surefire";
219     }
220 
221     protected String[] getDefaultIncludes()
222     {
223         return new String[]{ "**/Test*.java", "**/*Test.java", "**/*TestCase.java" };
224     }
225 
226     // now for the implementation of the field accessors
227 
228     public boolean isSkipTests()
229     {
230         return skipTests;
231     }
232 
233     public void setSkipTests( boolean skipTests )
234     {
235         this.skipTests = skipTests;
236     }
237 
238     /**
239      * @noinspection deprecation
240      */
241     public boolean isSkipExec()
242     {
243         return skipExec;
244     }
245 
246     /**
247      * @noinspection deprecation
248      */
249     public void setSkipExec( boolean skipExec )
250     {
251         this.skipExec = skipExec;
252     }
253 
254     public boolean isSkip()
255     {
256         return skip;
257     }
258 
259     public void setSkip( boolean skip )
260     {
261         this.skip = skip;
262     }
263 
264     public boolean isTestFailureIgnore()
265     {
266         return testFailureIgnore;
267     }
268 
269     public void setTestFailureIgnore( boolean testFailureIgnore )
270     {
271         this.testFailureIgnore = testFailureIgnore;
272     }
273 
274     public File getBasedir()
275     {
276         return basedir;
277     }
278 
279     public void setBasedir( File basedir )
280     {
281         this.basedir = basedir;
282     }
283 
284     public File getTestClassesDirectory()
285     {
286         return testClassesDirectory;
287     }
288 
289     public void setTestClassesDirectory( File testClassesDirectory )
290     {
291         this.testClassesDirectory = testClassesDirectory;
292     }
293 
294     public File getClassesDirectory()
295     {
296         return classesDirectory;
297     }
298 
299     public void setClassesDirectory( File classesDirectory )
300     {
301         this.classesDirectory = classesDirectory;
302     }
303 
304     public File getReportsDirectory()
305     {
306         return reportsDirectory;
307     }
308 
309     public void setReportsDirectory( File reportsDirectory )
310     {
311         this.reportsDirectory = reportsDirectory;
312     }
313 
314     public String getTest()
315     {
316         if ( StringUtils.isBlank( test ) )
317         {
318             return null;
319         }
320         String[] testArray = StringUtils.split( test, "," );
321         StringBuilder tests = new StringBuilder();
322         for ( String aTestArray : testArray )
323         {
324             String singleTest = aTestArray;
325             int index = singleTest.indexOf( '#' );
326             if ( index >= 0 )
327             {// the way version 2.7.3.  support single test method
328                 singleTest = singleTest.substring( 0, index );
329             }
330             tests.append( singleTest );
331             tests.append( "," );
332         }
333         return tests.toString();
334     }
335 
336     /**
337      * @since 2.7.3
338      */
339     public String getTestMethod()
340     {
341         if ( StringUtils.isBlank( test ) )
342         {
343             return null;
344         }
345         //modified by rainLee, see http://jira.codehaus.org/browse/SUREFIRE-745
346         int index = this.test.indexOf( '#' );
347         int index2 = this.test.indexOf( "," );
348         if ( index >= 0 )
349         {
350             if ( index2 < 0 )
351             {
352                 String testStrAfterFirstSharp = this.test.substring( index + 1, this.test.length() );
353                 if ( !testStrAfterFirstSharp.contains( "+" ) )
354                 {//the original way
355                     return testStrAfterFirstSharp;
356                 }
357                 else
358                 {
359                     return this.test;
360                 }
361             }
362             else
363             {
364                 return this.test;
365             }
366         }
367         return null;
368     }
369 
370     public boolean isUseSystemClassLoader()
371     {
372         return useSystemClassLoader;
373     }
374 
375     public void setUseSystemClassLoader( boolean useSystemClassLoader )
376     {
377         this.useSystemClassLoader = useSystemClassLoader;
378     }
379 
380     public boolean isUseManifestOnlyJar()
381     {
382         return useManifestOnlyJar;
383     }
384 
385     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
386     {
387         this.useManifestOnlyJar = useManifestOnlyJar;
388     }
389 
390     public Boolean getFailIfNoSpecifiedTests()
391     {
392         return failIfNoSpecifiedTests;
393     }
394 
395     public void setFailIfNoSpecifiedTests( Boolean failIfNoSpecifiedTests )
396     {
397         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
398     }
399 
400     public boolean isPrintSummary()
401     {
402         return printSummary;
403     }
404 
405     public void setPrintSummary( boolean printSummary )
406     {
407         this.printSummary = printSummary;
408     }
409 
410     public String getReportFormat()
411     {
412         return reportFormat;
413     }
414 
415     public void setReportFormat( String reportFormat )
416     {
417         this.reportFormat = reportFormat;
418     }
419 
420     public boolean isUseFile()
421     {
422         return useFile;
423     }
424 
425     public void setUseFile( boolean useFile )
426     {
427         this.useFile = useFile;
428     }
429 
430     public String getDebugForkedProcess()
431     {
432         return debugForkedProcess;
433     }
434 
435     public void setDebugForkedProcess( String debugForkedProcess )
436     {
437         this.debugForkedProcess = debugForkedProcess;
438     }
439 
440     public int getForkedProcessTimeoutInSeconds()
441     {
442         return forkedProcessTimeoutInSeconds;
443     }
444 
445     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
446     {
447         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
448     }
449 
450     public int getParallelTestsTimeoutInSeconds() {
451         return parallelTestsTimeoutInSeconds;
452     }
453 
454     public void setParallelTestsTimeoutInSeconds( int parallelTestsTimeoutInSeconds ) {
455         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
456     }
457 
458     public int getParallelTestsTimeoutForcedInSeconds() {
459         return parallelTestsTimeoutForcedInSeconds;
460     }
461 
462     public void setParallelTestsTimeoutForcedInSeconds( int parallelTestsTimeoutForcedInSeconds ) {
463         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
464     }
465 
466     public void setTest( String test )
467     {
468         this.test = test;
469     }
470 
471     @Override
472     public List<String> getIncludes()
473     {
474         return includes;
475     }
476 
477     @Override
478     public void setIncludes( List<String> includes )
479     {
480         this.includes = includes;
481     }
482 }