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>**/${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/**/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 <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 * <includes><br/> 169 * <include>**/Test*.java</include><br/> 170 * <include>**/*Test.java</include><br/> 171 * <include>**/*TestCase.java</include><br/> 172 * </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 * <include> entries.<br/> 177 * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):<br/> 178 * <include>%regex[.*[Cat|Dog].*], Basic????, !Unstable*</include><br/> 179 * <include>%regex[.*[Cat|Dog].*], !%regex[pkg.*Slow.*.class], pkg/**/*Fast*.java</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 <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 * */test/*<br/> 267 * **/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 * */test/*<br/> 277 * **/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 }