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".<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      * A list of &lt;include> elements specifying the tests (by pattern) that should be included in testing. When not
125      * specified and when the <code>test</code> parameter is not specified, the default includes will be <code><br/>
126      * &lt;includes><br/>
127      * &nbsp;&lt;include>**&#47;*Test*.java&lt;/include><br/>
128      * &nbsp;&lt;include>**&#47;*Test.java&lt;/include><br/>
129      * &nbsp;&lt;include>**&#47;*TestCase.java&lt;/include><br/>
130      * &lt;/includes><br/>
131      * </code>
132      * <p/>
133      * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple
134      * &nbsp;&lt;include> entries.<br/>
135      * <p/>
136      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
137      */
138     @Parameter
139     private List<String> includes;
140 
141     /**
142      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
143      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
144      * classloader.
145      *
146      * @since 2.3
147      */
148     @Parameter( property = "surefire.useSystemClassLoader", defaultValue = "true" )
149     private boolean useSystemClassLoader;
150 
151     /**
152      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
153      * launch your tests with a plain old Java classpath. (See
154      * http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html for a more detailed explanation
155      * of manifest-only JARs and their benefits.)
156      * <p/>
157      * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
158      *
159      * @since 2.4.3
160      */
161     @Parameter( property = "surefire.useManifestOnlyJar", defaultValue = "true" )
162     private boolean useManifestOnlyJar;
163 
164     protected void handleSummary( RunResult summary, NestedCheckedException firstForkException )
165         throws MojoExecutionException, MojoFailureException
166     {
167         assertNoException( firstForkException );
168 
169         SurefireHelper.reportExecution( this, summary, getLog() );
170     }
171 
172     private void assertNoException( NestedCheckedException firstForkException )
173         throws MojoFailureException
174     {
175         if ( firstForkException != null )
176         {
177             throw new MojoFailureException( firstForkException.getMessage(), firstForkException );
178         }
179     }
180 
181     private void assertNoFailureOrTimeout( NestedCheckedException summary )
182         throws MojoFailureException
183     {
184         if ( summary != null )
185         {
186             throw new MojoFailureException( "Failure or timeout" );
187         }
188     }
189 
190     protected boolean isSkipExecution()
191     {
192         return isSkip() || isSkipTests() || isSkipExec();
193     }
194 
195     protected String getPluginName()
196     {
197         return "surefire";
198     }
199 
200     protected String[] getDefaultIncludes()
201     {
202         return new String[]{ "**/Test*.java", "**/*Test.java", "**/*TestCase.java" };
203     }
204 
205     // now for the implementation of the field accessors
206 
207     public boolean isSkipTests()
208     {
209         return skipTests;
210     }
211 
212     public void setSkipTests( boolean skipTests )
213     {
214         this.skipTests = skipTests;
215     }
216 
217     /**
218      * @noinspection deprecation
219      */
220     public boolean isSkipExec()
221     {
222         return skipExec;
223     }
224 
225     /**
226      * @noinspection deprecation
227      */
228     public void setSkipExec( boolean skipExec )
229     {
230         this.skipExec = skipExec;
231     }
232 
233     public boolean isSkip()
234     {
235         return skip;
236     }
237 
238     public void setSkip( boolean skip )
239     {
240         this.skip = skip;
241     }
242 
243     public boolean isTestFailureIgnore()
244     {
245         return testFailureIgnore;
246     }
247 
248     public void setTestFailureIgnore( boolean testFailureIgnore )
249     {
250         this.testFailureIgnore = testFailureIgnore;
251     }
252 
253     public File getBasedir()
254     {
255         return basedir;
256     }
257 
258     public void setBasedir( File basedir )
259     {
260         this.basedir = basedir;
261     }
262 
263     public File getTestClassesDirectory()
264     {
265         return testClassesDirectory;
266     }
267 
268     public void setTestClassesDirectory( File testClassesDirectory )
269     {
270         this.testClassesDirectory = testClassesDirectory;
271     }
272 
273     public File getClassesDirectory()
274     {
275         return classesDirectory;
276     }
277 
278     public void setClassesDirectory( File classesDirectory )
279     {
280         this.classesDirectory = classesDirectory;
281     }
282 
283 
284     public List<String> getClasspathDependencyExcludes()
285     {
286         return classpathDependencyExcludes;
287     }
288 
289     public void setClasspathDependencyExcludes( List<String> classpathDependencyExcludes )
290     {
291         this.classpathDependencyExcludes = classpathDependencyExcludes;
292     }
293 
294     public String getClasspathDependencyScopeExclude()
295     {
296         return classpathDependencyScopeExclude;
297     }
298 
299     public void setClasspathDependencyScopeExclude( String classpathDependencyScopeExclude )
300     {
301         this.classpathDependencyScopeExclude = classpathDependencyScopeExclude;
302     }
303 
304     public List<String> getAdditionalClasspathElements()
305     {
306         return additionalClasspathElements;
307     }
308 
309     public void setAdditionalClasspathElements( List<String> additionalClasspathElements )
310     {
311         this.additionalClasspathElements = additionalClasspathElements;
312     }
313 
314     public File getReportsDirectory()
315     {
316         return reportsDirectory;
317     }
318 
319     public void setReportsDirectory( File reportsDirectory )
320     {
321         this.reportsDirectory = reportsDirectory;
322     }
323 
324     public String getTest()
325     {
326         if ( StringUtils.isBlank( test ) )
327         {
328             return null;
329         }
330         String[] testArray = StringUtils.split( test, "," );
331         StringBuilder tests = new StringBuilder();
332         for ( String aTestArray : testArray )
333         {
334             String singleTest = aTestArray;
335             int index = singleTest.indexOf( '#' );
336             if ( index >= 0 )
337             {// the way version 2.7.3.  support single test method
338                 singleTest = singleTest.substring( 0, index );
339             }
340             tests.append( singleTest );
341             tests.append( "," );
342         }
343         return tests.toString();
344     }
345 
346     /**
347      * @since 2.7.3
348      */
349     public String getTestMethod()
350     {
351         if ( StringUtils.isBlank( test ) )
352         {
353             return null;
354         }
355         //modified by rainLee, see http://jira.codehaus.org/browse/SUREFIRE-745
356         int index = this.test.indexOf( '#' );
357         int index2 = this.test.indexOf( "," );
358         if ( index >= 0 )
359         {
360             if ( index2 < 0 )
361             {
362                 String testStrAfterFirstSharp = this.test.substring( index + 1, this.test.length() );
363                 if ( !testStrAfterFirstSharp.contains( "+" ) )
364                 {//the original way
365                     return testStrAfterFirstSharp;
366                 }
367                 else
368                 {
369                     return this.test;
370                 }
371             }
372             else
373             {
374                 return this.test;
375             }
376         }
377         return null;
378     }
379 
380     public boolean isUseSystemClassLoader()
381     {
382         return useSystemClassLoader;
383     }
384 
385     public void setUseSystemClassLoader( boolean useSystemClassLoader )
386     {
387         this.useSystemClassLoader = useSystemClassLoader;
388     }
389 
390     public boolean isUseManifestOnlyJar()
391     {
392         return useManifestOnlyJar;
393     }
394 
395     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
396     {
397         this.useManifestOnlyJar = useManifestOnlyJar;
398     }
399 
400     public Boolean getFailIfNoSpecifiedTests()
401     {
402         return failIfNoSpecifiedTests;
403     }
404 
405     public void setFailIfNoSpecifiedTests( Boolean failIfNoSpecifiedTests )
406     {
407         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
408     }
409 
410     public boolean isPrintSummary()
411     {
412         return printSummary;
413     }
414 
415     public void setPrintSummary( boolean printSummary )
416     {
417         this.printSummary = printSummary;
418     }
419 
420     public String getReportFormat()
421     {
422         return reportFormat;
423     }
424 
425     public void setReportFormat( String reportFormat )
426     {
427         this.reportFormat = reportFormat;
428     }
429 
430     public boolean isUseFile()
431     {
432         return useFile;
433     }
434 
435     public void setUseFile( boolean useFile )
436     {
437         this.useFile = useFile;
438     }
439 
440     public String getDebugForkedProcess()
441     {
442         return debugForkedProcess;
443     }
444 
445     public void setDebugForkedProcess( String debugForkedProcess )
446     {
447         this.debugForkedProcess = debugForkedProcess;
448     }
449 
450     public int getForkedProcessTimeoutInSeconds()
451     {
452         return forkedProcessTimeoutInSeconds;
453     }
454 
455     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
456     {
457         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
458     }
459 
460     public void setTest( String test )
461     {
462         this.test = test;
463     }
464 
465     @Override
466     public List<String> getIncludes()
467     {
468         return includes;
469     }
470 
471     @Override
472     public void setIncludes( List<String> includes )
473     {
474         this.includes = includes;
475     }
476 }