1<?php 2/* 3 * This file is part of PHPUnit. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11use SebastianBergmann\CodeCoverage\CodeCoverage; 12use SebastianBergmann\CodeCoverage\Exception as CodeCoverageException; 13use SebastianBergmann\CodeCoverage\Filter as CodeCoverageFilter; 14use SebastianBergmann\CodeCoverage\Report\Clover as CloverReport; 15use SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport; 16use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport; 17use SebastianBergmann\CodeCoverage\Report\PHP as PhpReport; 18use SebastianBergmann\CodeCoverage\Report\Text as TextReport; 19use SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport; 20use SebastianBergmann\Environment\Runtime; 21 22/** 23 * A TestRunner for the Command Line Interface (CLI) 24 * PHP SAPI Module. 25 */ 26class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner 27{ 28 const SUCCESS_EXIT = 0; 29 const FAILURE_EXIT = 1; 30 const EXCEPTION_EXIT = 2; 31 32 /** 33 * @var CodeCoverageFilter 34 */ 35 protected $codeCoverageFilter; 36 37 /** 38 * @var PHPUnit_Runner_TestSuiteLoader 39 */ 40 protected $loader = null; 41 42 /** 43 * @var PHPUnit_TextUI_ResultPrinter 44 */ 45 protected $printer = null; 46 47 /** 48 * @var bool 49 */ 50 protected static $versionStringPrinted = false; 51 52 /** 53 * @var Runtime 54 */ 55 private $runtime; 56 57 /** 58 * @var bool 59 */ 60 private $messagePrinted = false; 61 62 /** 63 * @param PHPUnit_Runner_TestSuiteLoader $loader 64 * @param CodeCoverageFilter $filter 65 */ 66 public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = null, CodeCoverageFilter $filter = null) 67 { 68 if ($filter === null) { 69 $filter = new CodeCoverageFilter; 70 } 71 72 $this->codeCoverageFilter = $filter; 73 $this->loader = $loader; 74 $this->runtime = new Runtime; 75 } 76 77 /** 78 * @param PHPUnit_Framework_Test|ReflectionClass $test 79 * @param array $arguments 80 * 81 * @return PHPUnit_Framework_TestResult 82 * 83 * @throws PHPUnit_Framework_Exception 84 */ 85 public static function run($test, array $arguments = []) 86 { 87 if ($test instanceof ReflectionClass) { 88 $test = new PHPUnit_Framework_TestSuite($test); 89 } 90 91 if ($test instanceof PHPUnit_Framework_Test) { 92 $aTestRunner = new self; 93 94 return $aTestRunner->doRun( 95 $test, 96 $arguments 97 ); 98 } else { 99 throw new PHPUnit_Framework_Exception( 100 'No test case or test suite found.' 101 ); 102 } 103 } 104 105 /** 106 * @return PHPUnit_Framework_TestResult 107 */ 108 protected function createTestResult() 109 { 110 return new PHPUnit_Framework_TestResult; 111 } 112 113 /** 114 * @param PHPUnit_Framework_TestSuite $suite 115 * @param array $arguments 116 */ 117 private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments) 118 { 119 if (!$arguments['filter'] && 120 empty($arguments['groups']) && 121 empty($arguments['excludeGroups'])) { 122 return; 123 } 124 125 $filterFactory = new PHPUnit_Runner_Filter_Factory(); 126 127 if (!empty($arguments['excludeGroups'])) { 128 $filterFactory->addFilter( 129 new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'), 130 $arguments['excludeGroups'] 131 ); 132 } 133 134 if (!empty($arguments['groups'])) { 135 $filterFactory->addFilter( 136 new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'), 137 $arguments['groups'] 138 ); 139 } 140 141 if ($arguments['filter']) { 142 $filterFactory->addFilter( 143 new ReflectionClass('PHPUnit_Runner_Filter_Test'), 144 $arguments['filter'] 145 ); 146 } 147 $suite->injectFilter($filterFactory); 148 } 149 150 /** 151 * @param PHPUnit_Framework_Test $suite 152 * @param array $arguments 153 * @param bool $exit 154 * 155 * @return PHPUnit_Framework_TestResult 156 */ 157 public function doRun(PHPUnit_Framework_Test $suite, array $arguments = [], $exit = true) 158 { 159 if (isset($arguments['configuration'])) { 160 $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] = $arguments['configuration']; 161 } 162 163 $this->handleConfiguration($arguments); 164 165 $this->processSuiteFilters($suite, $arguments); 166 167 if (isset($arguments['bootstrap'])) { 168 $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap']; 169 } 170 171 if ($arguments['backupGlobals'] === false) { 172 $suite->setBackupGlobals(false); 173 } 174 175 if ($arguments['backupStaticAttributes'] === true) { 176 $suite->setBackupStaticAttributes(true); 177 } 178 179 if ($arguments['beStrictAboutChangesToGlobalState'] === true) { 180 $suite->setBeStrictAboutChangesToGlobalState(true); 181 } 182 183 if (is_int($arguments['repeat'])) { 184 $test = new PHPUnit_Extensions_RepeatedTest( 185 $suite, 186 $arguments['repeat'], 187 $arguments['processIsolation'] 188 ); 189 190 $suite = new PHPUnit_Framework_TestSuite(); 191 $suite->addTest($test); 192 } 193 194 $result = $this->createTestResult(); 195 196 if (!$arguments['convertErrorsToExceptions']) { 197 $result->convertErrorsToExceptions(false); 198 } 199 200 if (!$arguments['convertNoticesToExceptions']) { 201 PHPUnit_Framework_Error_Notice::$enabled = false; 202 } 203 204 if (!$arguments['convertWarningsToExceptions']) { 205 PHPUnit_Framework_Error_Warning::$enabled = false; 206 } 207 208 if ($arguments['stopOnError']) { 209 $result->stopOnError(true); 210 } 211 212 if ($arguments['stopOnFailure']) { 213 $result->stopOnFailure(true); 214 } 215 216 if ($arguments['stopOnWarning']) { 217 $result->stopOnWarning(true); 218 } 219 220 if ($arguments['stopOnIncomplete']) { 221 $result->stopOnIncomplete(true); 222 } 223 224 if ($arguments['stopOnRisky']) { 225 $result->stopOnRisky(true); 226 } 227 228 if ($arguments['stopOnSkipped']) { 229 $result->stopOnSkipped(true); 230 } 231 232 if ($arguments['registerMockObjectsFromTestArgumentsRecursively']) { 233 $result->setRegisterMockObjectsFromTestArgumentsRecursively(true); 234 } 235 236 if ($this->printer === null) { 237 if (isset($arguments['printer']) && 238 $arguments['printer'] instanceof PHPUnit_Util_Printer) { 239 $this->printer = $arguments['printer']; 240 } else { 241 $printerClass = 'PHPUnit_TextUI_ResultPrinter'; 242 243 if (isset($arguments['printer']) && 244 is_string($arguments['printer']) && 245 class_exists($arguments['printer'], false)) { 246 $class = new ReflectionClass($arguments['printer']); 247 248 if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) { 249 $printerClass = $arguments['printer']; 250 } 251 } 252 253 $this->printer = new $printerClass( 254 (isset($arguments['stderr']) && $arguments['stderr'] === true) ? 'php://stderr' : null, 255 $arguments['verbose'], 256 $arguments['colors'], 257 $arguments['debug'], 258 $arguments['columns'], 259 $arguments['reverseList'] 260 ); 261 } 262 } 263 264 if (!$this->printer instanceof PHPUnit_Util_Log_TAP) { 265 $this->printer->write( 266 PHPUnit_Runner_Version::getVersionString() . "\n" 267 ); 268 269 self::$versionStringPrinted = true; 270 271 if ($arguments['verbose']) { 272 $runtime = $this->runtime->getNameWithVersion(); 273 274 if ($this->runtime->hasXdebug()) { 275 $runtime .= sprintf( 276 ' with Xdebug %s', 277 phpversion('xdebug') 278 ); 279 } 280 281 $this->writeMessage('Runtime', $runtime); 282 283 if (isset($arguments['configuration'])) { 284 $this->writeMessage( 285 'Configuration', 286 $arguments['configuration']->getFilename() 287 ); 288 } 289 290 foreach ($arguments['loadedExtensions'] as $extension) { 291 $this->writeMessage( 292 'Extension', 293 $extension 294 ); 295 } 296 297 foreach ($arguments['notLoadedExtensions'] as $extension) { 298 $this->writeMessage( 299 'Extension', 300 $extension 301 ); 302 } 303 } 304 305 if (isset($arguments['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'])) { 306 $this->writeMessage('Warning', 'Deprecated configuration setting "checkForUnintentionallyCoveredCode" used'); 307 } 308 309 if (isset($arguments['tapLogfile'])) { 310 $this->writeMessage('Warning', 'Deprecated TAP test listener used'); 311 } 312 313 if (isset($arguments['jsonLogfile'])) { 314 $this->writeMessage('Warning', 'Deprecated JSON test listener used'); 315 } 316 } 317 318 foreach ($arguments['listeners'] as $listener) { 319 $result->addListener($listener); 320 } 321 322 $result->addListener($this->printer); 323 324 if (isset($arguments['testdoxHTMLFile'])) { 325 $result->addListener( 326 new PHPUnit_Util_TestDox_ResultPrinter_HTML( 327 $arguments['testdoxHTMLFile'], 328 $arguments['testdoxGroups'], 329 $arguments['testdoxExcludeGroups'] 330 ) 331 ); 332 } 333 334 if (isset($arguments['testdoxTextFile'])) { 335 $result->addListener( 336 new PHPUnit_Util_TestDox_ResultPrinter_Text( 337 $arguments['testdoxTextFile'], 338 $arguments['testdoxGroups'], 339 $arguments['testdoxExcludeGroups'] 340 ) 341 ); 342 } 343 344 if (isset($arguments['testdoxXMLFile'])) { 345 $result->addListener( 346 new PHPUnit_Util_TestDox_ResultPrinter_XML( 347 $arguments['testdoxXMLFile'] 348 ) 349 ); 350 } 351 352 $codeCoverageReports = 0; 353 354 if (isset($arguments['coverageClover'])) { 355 $codeCoverageReports++; 356 } 357 358 if (isset($arguments['coverageCrap4J'])) { 359 $codeCoverageReports++; 360 } 361 362 if (isset($arguments['coverageHtml'])) { 363 $codeCoverageReports++; 364 } 365 366 if (isset($arguments['coveragePHP'])) { 367 $codeCoverageReports++; 368 } 369 370 if (isset($arguments['coverageText'])) { 371 $codeCoverageReports++; 372 } 373 374 if (isset($arguments['coverageXml'])) { 375 $codeCoverageReports++; 376 } 377 378 if (isset($arguments['noCoverage'])) { 379 $codeCoverageReports = 0; 380 } 381 382 if ($codeCoverageReports > 0 && !$this->runtime->canCollectCodeCoverage()) { 383 $this->writeMessage('Error', 'No code coverage driver is available'); 384 385 $codeCoverageReports = 0; 386 } 387 388 if (!$this->printer instanceof PHPUnit_Util_Log_TAP) { 389 $this->printer->write("\n"); 390 } 391 392 if ($codeCoverageReports > 0) { 393 $codeCoverage = new CodeCoverage( 394 null, 395 $this->codeCoverageFilter 396 ); 397 398 $codeCoverage->setUnintentionallyCoveredSubclassesWhitelist( 399 [SebastianBergmann\Comparator\Comparator::class] 400 ); 401 402 $codeCoverage->setCheckForUnintentionallyCoveredCode( 403 $arguments['strictCoverage'] 404 ); 405 406 $codeCoverage->setCheckForMissingCoversAnnotation( 407 $arguments['strictCoverage'] 408 ); 409 410 if (isset($arguments['forceCoversAnnotation'])) { 411 $codeCoverage->setForceCoversAnnotation( 412 $arguments['forceCoversAnnotation'] 413 ); 414 } 415 416 if (isset($arguments['disableCodeCoverageIgnore'])) { 417 $codeCoverage->setDisableIgnoredLines(true); 418 } 419 420 if (isset($arguments['whitelist'])) { 421 $this->codeCoverageFilter->addDirectoryToWhitelist($arguments['whitelist']); 422 } 423 424 if (isset($arguments['configuration'])) { 425 $filterConfiguration = $arguments['configuration']->getFilterConfiguration(); 426 427 $codeCoverage->setAddUncoveredFilesFromWhitelist( 428 $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'] 429 ); 430 431 $codeCoverage->setProcessUncoveredFilesFromWhitelist( 432 $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'] 433 ); 434 435 foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) { 436 $this->codeCoverageFilter->addDirectoryToWhitelist( 437 $dir['path'], 438 $dir['suffix'], 439 $dir['prefix'] 440 ); 441 } 442 443 foreach ($filterConfiguration['whitelist']['include']['file'] as $file) { 444 $this->codeCoverageFilter->addFileToWhitelist($file); 445 } 446 447 foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) { 448 $this->codeCoverageFilter->removeDirectoryFromWhitelist( 449 $dir['path'], 450 $dir['suffix'], 451 $dir['prefix'] 452 ); 453 } 454 455 foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) { 456 $this->codeCoverageFilter->removeFileFromWhitelist($file); 457 } 458 } 459 460 if (!$this->codeCoverageFilter->hasWhitelist()) { 461 $this->writeMessage('Error', 'No whitelist configured, no code coverage will be generated'); 462 463 $codeCoverageReports = 0; 464 465 unset($codeCoverage); 466 } 467 } 468 469 if (isset($codeCoverage)) { 470 $result->setCodeCoverage($codeCoverage); 471 472 if ($codeCoverageReports > 1 && isset($arguments['cacheTokens'])) { 473 $codeCoverage->setCacheTokens($arguments['cacheTokens']); 474 } 475 } 476 477 if (isset($arguments['jsonLogfile'])) { 478 $result->addListener( 479 new PHPUnit_Util_Log_JSON($arguments['jsonLogfile']) 480 ); 481 } 482 483 if (isset($arguments['tapLogfile'])) { 484 $result->addListener( 485 new PHPUnit_Util_Log_TAP($arguments['tapLogfile']) 486 ); 487 } 488 489 if (isset($arguments['teamcityLogfile'])) { 490 $result->addListener( 491 new PHPUnit_Util_Log_TeamCity($arguments['teamcityLogfile']) 492 ); 493 } 494 495 if (isset($arguments['junitLogfile'])) { 496 $result->addListener( 497 new PHPUnit_Util_Log_JUnit( 498 $arguments['junitLogfile'], 499 $arguments['logIncompleteSkipped'] 500 ) 501 ); 502 } 503 504 $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']); 505 $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']); 506 $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']); 507 $result->beStrictAboutResourceUsageDuringSmallTests($arguments['beStrictAboutResourceUsageDuringSmallTests']); 508 $result->enforceTimeLimit($arguments['enforceTimeLimit']); 509 $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']); 510 $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']); 511 $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']); 512 513 if ($suite instanceof PHPUnit_Framework_TestSuite) { 514 $suite->setRunTestInSeparateProcess($arguments['processIsolation']); 515 } 516 517 $suite->run($result); 518 519 unset($suite); 520 $result->flushListeners(); 521 522 if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { 523 $this->printer->printResult($result); 524 } 525 526 if (isset($codeCoverage)) { 527 if (isset($arguments['coverageClover'])) { 528 $this->printer->write( 529 "\nGenerating code coverage report in Clover XML format ..." 530 ); 531 532 try { 533 $writer = new CloverReport(); 534 $writer->process($codeCoverage, $arguments['coverageClover']); 535 536 $this->printer->write(" done\n"); 537 unset($writer); 538 } catch (CodeCoverageException $e) { 539 $this->printer->write( 540 " failed\n" . $e->getMessage() . "\n" 541 ); 542 } 543 } 544 545 if (isset($arguments['coverageCrap4J'])) { 546 $this->printer->write( 547 "\nGenerating Crap4J report XML file ..." 548 ); 549 550 try { 551 $writer = new Crap4jReport($arguments['crap4jThreshold']); 552 $writer->process($codeCoverage, $arguments['coverageCrap4J']); 553 554 $this->printer->write(" done\n"); 555 unset($writer); 556 } catch (CodeCoverageException $e) { 557 $this->printer->write( 558 " failed\n" . $e->getMessage() . "\n" 559 ); 560 } 561 } 562 563 if (isset($arguments['coverageHtml'])) { 564 $this->printer->write( 565 "\nGenerating code coverage report in HTML format ..." 566 ); 567 568 try { 569 $writer = new HtmlReport( 570 $arguments['reportLowUpperBound'], 571 $arguments['reportHighLowerBound'], 572 sprintf( 573 ' and <a href="https://phpunit.de/">PHPUnit %s</a>', 574 PHPUnit_Runner_Version::id() 575 ) 576 ); 577 578 $writer->process($codeCoverage, $arguments['coverageHtml']); 579 580 $this->printer->write(" done\n"); 581 unset($writer); 582 } catch (CodeCoverageException $e) { 583 $this->printer->write( 584 " failed\n" . $e->getMessage() . "\n" 585 ); 586 } 587 } 588 589 if (isset($arguments['coveragePHP'])) { 590 $this->printer->write( 591 "\nGenerating code coverage report in PHP format ..." 592 ); 593 594 try { 595 $writer = new PhpReport(); 596 $writer->process($codeCoverage, $arguments['coveragePHP']); 597 598 $this->printer->write(" done\n"); 599 unset($writer); 600 } catch (CodeCoverageException $e) { 601 $this->printer->write( 602 " failed\n" . $e->getMessage() . "\n" 603 ); 604 } 605 } 606 607 if (isset($arguments['coverageText'])) { 608 if ($arguments['coverageText'] == 'php://stdout') { 609 $outputStream = $this->printer; 610 $colors = $arguments['colors'] && $arguments['colors'] != PHPUnit_TextUI_ResultPrinter::COLOR_NEVER; 611 } else { 612 $outputStream = new PHPUnit_Util_Printer($arguments['coverageText']); 613 $colors = false; 614 } 615 616 $processor = new TextReport( 617 $arguments['reportLowUpperBound'], 618 $arguments['reportHighLowerBound'], 619 $arguments['coverageTextShowUncoveredFiles'], 620 $arguments['coverageTextShowOnlySummary'] 621 ); 622 623 $outputStream->write( 624 $processor->process($codeCoverage, $colors) 625 ); 626 } 627 628 if (isset($arguments['coverageXml'])) { 629 $this->printer->write( 630 "\nGenerating code coverage report in PHPUnit XML format ..." 631 ); 632 633 try { 634 $writer = new XmlReport; 635 $writer->process($codeCoverage, $arguments['coverageXml']); 636 637 $this->printer->write(" done\n"); 638 unset($writer); 639 } catch (CodeCoverageException $e) { 640 $this->printer->write( 641 " failed\n" . $e->getMessage() . "\n" 642 ); 643 } 644 } 645 } 646 647 if ($exit) { 648 if ($result->wasSuccessful(false)) { 649 if ($arguments['failOnRisky'] && !$result->allHarmless()) { 650 exit(self::FAILURE_EXIT); 651 } 652 653 if ($arguments['failOnWarning'] && $result->warningCount() > 0) { 654 exit(self::FAILURE_EXIT); 655 } 656 657 exit(self::SUCCESS_EXIT); 658 } 659 660 if ($result->errorCount() > 0) { 661 exit(self::EXCEPTION_EXIT); 662 } 663 664 if ($result->failureCount() > 0) { 665 exit(self::FAILURE_EXIT); 666 } 667 } 668 669 return $result; 670 } 671 672 /** 673 * @param PHPUnit_TextUI_ResultPrinter $resultPrinter 674 */ 675 public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter) 676 { 677 $this->printer = $resultPrinter; 678 } 679 680 /** 681 * Override to define how to handle a failed loading of 682 * a test suite. 683 * 684 * @param string $message 685 */ 686 protected function runFailed($message) 687 { 688 $this->write($message . PHP_EOL); 689 exit(self::FAILURE_EXIT); 690 } 691 692 /** 693 * @param string $buffer 694 */ 695 protected function write($buffer) 696 { 697 if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') { 698 $buffer = htmlspecialchars($buffer); 699 } 700 701 if ($this->printer !== null) { 702 $this->printer->write($buffer); 703 } else { 704 print $buffer; 705 } 706 } 707 708 /** 709 * Returns the loader to be used. 710 * 711 * @return PHPUnit_Runner_TestSuiteLoader 712 */ 713 public function getLoader() 714 { 715 if ($this->loader === null) { 716 $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader; 717 } 718 719 return $this->loader; 720 } 721 722 /** 723 * @param array $arguments 724 */ 725 protected function handleConfiguration(array &$arguments) 726 { 727 if (isset($arguments['configuration']) && 728 !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) { 729 $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance( 730 $arguments['configuration'] 731 ); 732 } 733 734 $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : false; 735 $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : false; 736 $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : []; 737 738 if (isset($arguments['configuration'])) { 739 $arguments['configuration']->handlePHPConfiguration(); 740 741 $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration(); 742 743 if (isset($phpunitConfiguration['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'])) { 744 $arguments['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'] = true; 745 } 746 747 if (isset($phpunitConfiguration['backupGlobals']) && 748 !isset($arguments['backupGlobals'])) { 749 $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals']; 750 } 751 752 if (isset($phpunitConfiguration['backupStaticAttributes']) && 753 !isset($arguments['backupStaticAttributes'])) { 754 $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes']; 755 } 756 757 if (isset($phpunitConfiguration['beStrictAboutChangesToGlobalState']) && 758 !isset($arguments['beStrictAboutChangesToGlobalState'])) { 759 $arguments['beStrictAboutChangesToGlobalState'] = $phpunitConfiguration['beStrictAboutChangesToGlobalState']; 760 } 761 762 if (isset($phpunitConfiguration['bootstrap']) && 763 !isset($arguments['bootstrap'])) { 764 $arguments['bootstrap'] = $phpunitConfiguration['bootstrap']; 765 } 766 767 if (isset($phpunitConfiguration['cacheTokens']) && 768 !isset($arguments['cacheTokens'])) { 769 $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens']; 770 } 771 772 if (isset($phpunitConfiguration['colors']) && 773 !isset($arguments['colors'])) { 774 $arguments['colors'] = $phpunitConfiguration['colors']; 775 } 776 777 if (isset($phpunitConfiguration['convertErrorsToExceptions']) && 778 !isset($arguments['convertErrorsToExceptions'])) { 779 $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions']; 780 } 781 782 if (isset($phpunitConfiguration['convertNoticesToExceptions']) && 783 !isset($arguments['convertNoticesToExceptions'])) { 784 $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions']; 785 } 786 787 if (isset($phpunitConfiguration['convertWarningsToExceptions']) && 788 !isset($arguments['convertWarningsToExceptions'])) { 789 $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions']; 790 } 791 792 if (isset($phpunitConfiguration['processIsolation']) && 793 !isset($arguments['processIsolation'])) { 794 $arguments['processIsolation'] = $phpunitConfiguration['processIsolation']; 795 } 796 797 if (isset($phpunitConfiguration['stopOnError']) && 798 !isset($arguments['stopOnError'])) { 799 $arguments['stopOnError'] = $phpunitConfiguration['stopOnError']; 800 } 801 802 if (isset($phpunitConfiguration['stopOnFailure']) && 803 !isset($arguments['stopOnFailure'])) { 804 $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure']; 805 } 806 807 if (isset($phpunitConfiguration['stopOnWarning']) && 808 !isset($arguments['stopOnWarning'])) { 809 $arguments['stopOnWarning'] = $phpunitConfiguration['stopOnWarning']; 810 } 811 812 if (isset($phpunitConfiguration['stopOnIncomplete']) && 813 !isset($arguments['stopOnIncomplete'])) { 814 $arguments['stopOnIncomplete'] = $phpunitConfiguration['stopOnIncomplete']; 815 } 816 817 if (isset($phpunitConfiguration['stopOnRisky']) && 818 !isset($arguments['stopOnRisky'])) { 819 $arguments['stopOnRisky'] = $phpunitConfiguration['stopOnRisky']; 820 } 821 822 if (isset($phpunitConfiguration['stopOnSkipped']) && 823 !isset($arguments['stopOnSkipped'])) { 824 $arguments['stopOnSkipped'] = $phpunitConfiguration['stopOnSkipped']; 825 } 826 827 if (isset($phpunitConfiguration['failOnWarning']) && 828 !isset($arguments['failOnWarning'])) { 829 $arguments['failOnWarning'] = $phpunitConfiguration['failOnWarning']; 830 } 831 832 if (isset($phpunitConfiguration['failOnRisky']) && 833 !isset($arguments['failOnRisky'])) { 834 $arguments['failOnRisky'] = $phpunitConfiguration['failOnRisky']; 835 } 836 837 if (isset($phpunitConfiguration['timeoutForSmallTests']) && 838 !isset($arguments['timeoutForSmallTests'])) { 839 $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests']; 840 } 841 842 if (isset($phpunitConfiguration['timeoutForMediumTests']) && 843 !isset($arguments['timeoutForMediumTests'])) { 844 $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests']; 845 } 846 847 if (isset($phpunitConfiguration['timeoutForLargeTests']) && 848 !isset($arguments['timeoutForLargeTests'])) { 849 $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests']; 850 } 851 852 if (isset($phpunitConfiguration['reportUselessTests']) && 853 !isset($arguments['reportUselessTests'])) { 854 $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests']; 855 } 856 857 if (isset($phpunitConfiguration['strictCoverage']) && 858 !isset($arguments['strictCoverage'])) { 859 $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage']; 860 } 861 862 if (isset($phpunitConfiguration['disallowTestOutput']) && 863 !isset($arguments['disallowTestOutput'])) { 864 $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput']; 865 } 866 867 if (isset($phpunitConfiguration['enforceTimeLimit']) && 868 !isset($arguments['enforceTimeLimit'])) { 869 $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit']; 870 } 871 872 if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) && 873 !isset($arguments['disallowTodoAnnotatedTests'])) { 874 $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests']; 875 } 876 877 if (isset($phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']) && 878 !isset($arguments['beStrictAboutResourceUsageDuringSmallTests'])) { 879 $arguments['beStrictAboutResourceUsageDuringSmallTests'] = $phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']; 880 } 881 882 if (isset($phpunitConfiguration['verbose']) && 883 !isset($arguments['verbose'])) { 884 $arguments['verbose'] = $phpunitConfiguration['verbose']; 885 } 886 887 if (isset($phpunitConfiguration['reverseDefectList']) && 888 !isset($arguments['reverseList'])) { 889 $arguments['reverseList'] = $phpunitConfiguration['reverseDefectList']; 890 } 891 892 if (isset($phpunitConfiguration['forceCoversAnnotation']) && 893 !isset($arguments['forceCoversAnnotation'])) { 894 $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation']; 895 } 896 897 if (isset($phpunitConfiguration['disableCodeCoverageIgnore']) && 898 !isset($arguments['disableCodeCoverageIgnore'])) { 899 $arguments['disableCodeCoverageIgnore'] = $phpunitConfiguration['disableCodeCoverageIgnore']; 900 } 901 902 if (isset($phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']) && 903 !isset($arguments['registerMockObjectsFromTestArgumentsRecursively'])) { 904 $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']; 905 } 906 907 $groupCliArgs = []; 908 909 if (!empty($arguments['groups'])) { 910 $groupCliArgs = $arguments['groups']; 911 } 912 913 $groupConfiguration = $arguments['configuration']->getGroupConfiguration(); 914 915 if (!empty($groupConfiguration['include']) && 916 !isset($arguments['groups'])) { 917 $arguments['groups'] = $groupConfiguration['include']; 918 } 919 920 if (!empty($groupConfiguration['exclude']) && 921 !isset($arguments['excludeGroups'])) { 922 $arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs); 923 } 924 925 foreach ($arguments['configuration']->getListenerConfiguration() as $listener) { 926 if (!class_exists($listener['class'], false) && 927 $listener['file'] !== '') { 928 require_once $listener['file']; 929 } 930 931 if (!class_exists($listener['class'])) { 932 throw new PHPUnit_Framework_Exception( 933 sprintf( 934 'Class "%s" does not exist', 935 $listener['class'] 936 ) 937 ); 938 } 939 940 $listenerClass = new ReflectionClass($listener['class']); 941 942 if (!$listenerClass->implementsInterface(PHPUnit_Framework_TestListener::class)) { 943 throw new PHPUnit_Framework_Exception( 944 sprintf( 945 'Class "%s" does not implement the PHPUnit_Framework_TestListener interface', 946 $listener['class'] 947 ) 948 ); 949 } 950 951 if (count($listener['arguments']) == 0) { 952 $listener = new $listener['class']; 953 } else { 954 $listener = $listenerClass->newInstanceArgs( 955 $listener['arguments'] 956 ); 957 } 958 959 $arguments['listeners'][] = $listener; 960 } 961 962 $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); 963 964 if (isset($loggingConfiguration['coverage-clover']) && 965 !isset($arguments['coverageClover'])) { 966 $arguments['coverageClover'] = $loggingConfiguration['coverage-clover']; 967 } 968 969 if (isset($loggingConfiguration['coverage-crap4j']) && 970 !isset($arguments['coverageCrap4J'])) { 971 $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j']; 972 973 if (isset($loggingConfiguration['crap4jThreshold']) && 974 !isset($arguments['crap4jThreshold'])) { 975 $arguments['crap4jThreshold'] = $loggingConfiguration['crap4jThreshold']; 976 } 977 } 978 979 if (isset($loggingConfiguration['coverage-html']) && 980 !isset($arguments['coverageHtml'])) { 981 if (isset($loggingConfiguration['lowUpperBound']) && 982 !isset($arguments['reportLowUpperBound'])) { 983 $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound']; 984 } 985 986 if (isset($loggingConfiguration['highLowerBound']) && 987 !isset($arguments['reportHighLowerBound'])) { 988 $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound']; 989 } 990 991 $arguments['coverageHtml'] = $loggingConfiguration['coverage-html']; 992 } 993 994 if (isset($loggingConfiguration['coverage-php']) && 995 !isset($arguments['coveragePHP'])) { 996 $arguments['coveragePHP'] = $loggingConfiguration['coverage-php']; 997 } 998 999 if (isset($loggingConfiguration['coverage-text']) && 1000 !isset($arguments['coverageText'])) { 1001 $arguments['coverageText'] = $loggingConfiguration['coverage-text']; 1002 if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) { 1003 $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles']; 1004 } else { 1005 $arguments['coverageTextShowUncoveredFiles'] = false; 1006 } 1007 if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) { 1008 $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary']; 1009 } else { 1010 $arguments['coverageTextShowOnlySummary'] = false; 1011 } 1012 } 1013 1014 if (isset($loggingConfiguration['coverage-xml']) && 1015 !isset($arguments['coverageXml'])) { 1016 $arguments['coverageXml'] = $loggingConfiguration['coverage-xml']; 1017 } 1018 1019 if (isset($loggingConfiguration['json']) && 1020 !isset($arguments['jsonLogfile'])) { 1021 $arguments['jsonLogfile'] = $loggingConfiguration['json']; 1022 } 1023 1024 if (isset($loggingConfiguration['plain'])) { 1025 $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter( 1026 $loggingConfiguration['plain'], 1027 true 1028 ); 1029 } 1030 1031 if (isset($loggingConfiguration['tap']) && 1032 !isset($arguments['tapLogfile'])) { 1033 $arguments['tapLogfile'] = $loggingConfiguration['tap']; 1034 } 1035 1036 if (isset($loggingConfiguration['teamcity']) && 1037 !isset($arguments['teamcityLogfile'])) { 1038 $arguments['teamcityLogfile'] = $loggingConfiguration['teamcity']; 1039 } 1040 1041 if (isset($loggingConfiguration['junit']) && 1042 !isset($arguments['junitLogfile'])) { 1043 $arguments['junitLogfile'] = $loggingConfiguration['junit']; 1044 1045 if (isset($loggingConfiguration['logIncompleteSkipped']) && 1046 !isset($arguments['logIncompleteSkipped'])) { 1047 $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped']; 1048 } 1049 } 1050 1051 if (isset($loggingConfiguration['testdox-html']) && 1052 !isset($arguments['testdoxHTMLFile'])) { 1053 $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html']; 1054 } 1055 1056 if (isset($loggingConfiguration['testdox-text']) && 1057 !isset($arguments['testdoxTextFile'])) { 1058 $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text']; 1059 } 1060 1061 if (isset($loggingConfiguration['testdox-xml']) && 1062 !isset($arguments['testdoxXMLFile'])) { 1063 $arguments['testdoxXMLFile'] = $loggingConfiguration['testdox-xml']; 1064 } 1065 1066 $testdoxGroupConfiguration = $arguments['configuration']->getTestdoxGroupConfiguration(); 1067 1068 if (isset($testdoxGroupConfiguration['include']) && 1069 !isset($arguments['testdoxGroups'])) { 1070 $arguments['testdoxGroups'] = $testdoxGroupConfiguration['include']; 1071 } 1072 1073 if (isset($testdoxGroupConfiguration['exclude']) && 1074 !isset($arguments['testdoxExcludeGroups'])) { 1075 $arguments['testdoxExcludeGroups'] = $testdoxGroupConfiguration['exclude']; 1076 } 1077 } 1078 1079 $arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : true; 1080 $arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : false; 1081 $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : null; 1082 $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : null; 1083 $arguments['beStrictAboutChangesToGlobalState'] = isset($arguments['beStrictAboutChangesToGlobalState']) ? $arguments['beStrictAboutChangesToGlobalState'] : null; 1084 $arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : false; 1085 $arguments['columns'] = isset($arguments['columns']) ? $arguments['columns'] : 80; 1086 $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : PHPUnit_TextUI_ResultPrinter::COLOR_DEFAULT; 1087 $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : true; 1088 $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : true; 1089 $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : true; 1090 $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : []; 1091 $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : []; 1092 $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : false; 1093 $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : false; 1094 $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : false; 1095 $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90; 1096 $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50; 1097 $arguments['crap4jThreshold'] = isset($arguments['crap4jThreshold']) ? $arguments['crap4jThreshold'] : 30; 1098 $arguments['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : false; 1099 $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : false; 1100 $arguments['stopOnWarning'] = isset($arguments['stopOnWarning']) ? $arguments['stopOnWarning'] : false; 1101 $arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : false; 1102 $arguments['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : false; 1103 $arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : false; 1104 $arguments['failOnWarning'] = isset($arguments['failOnWarning']) ? $arguments['failOnWarning'] : false; 1105 $arguments['failOnRisky'] = isset($arguments['failOnRisky']) ? $arguments['failOnRisky'] : false; 1106 $arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1; 1107 $arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10; 1108 $arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60; 1109 $arguments['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false; 1110 $arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false; 1111 $arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false; 1112 $arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false; 1113 $arguments['disallowTodoAnnotatedTests'] = isset($arguments['disallowTodoAnnotatedTests']) ? $arguments['disallowTodoAnnotatedTests'] : false; 1114 $arguments['beStrictAboutResourceUsageDuringSmallTests'] = isset($arguments['beStrictAboutResourceUsageDuringSmallTests']) ? $arguments['beStrictAboutResourceUsageDuringSmallTests'] : false; 1115 $arguments['reverseList'] = isset($arguments['reverseList']) ? $arguments['reverseList'] : false; 1116 $arguments['registerMockObjectsFromTestArgumentsRecursively'] = isset($arguments['registerMockObjectsFromTestArgumentsRecursively']) ? $arguments['registerMockObjectsFromTestArgumentsRecursively'] : false; 1117 $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false; 1118 $arguments['testdoxExcludeGroups'] = isset($arguments['testdoxExcludeGroups']) ? $arguments['testdoxExcludeGroups'] : []; 1119 $arguments['testdoxGroups'] = isset($arguments['testdoxGroups']) ? $arguments['testdoxGroups'] : []; 1120 } 1121 1122 /** 1123 * @param string $type 1124 * @param string $message 1125 */ 1126 private function writeMessage($type, $message) 1127 { 1128 if (!$this->messagePrinted) { 1129 $this->write("\n"); 1130 } 1131 1132 $this->write( 1133 sprintf( 1134 "%-15s%s\n", 1135 $type . ':', 1136 $message 1137 ) 1138 ); 1139 1140 $this->messagePrinted = true; 1141 } 1142} 1143