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