Command.php (34188B)
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 11 /** 12 * A TestRunner for the Command Line Interface (CLI) 13 * PHP SAPI Module. 14 * 15 * @since Class available since Release 3.0.0 16 */ 17 class PHPUnit_TextUI_Command 18 { 19 /** 20 * @var array 21 */ 22 protected $arguments = array( 23 'listGroups' => false, 24 'loader' => null, 25 'useDefaultConfiguration' => true 26 ); 27 28 /** 29 * @var array 30 */ 31 protected $options = array(); 32 33 /** 34 * @var array 35 */ 36 protected $longOptions = array( 37 'colors==' => null, 38 'bootstrap=' => null, 39 'columns=' => null, 40 'configuration=' => null, 41 'coverage-clover=' => null, 42 'coverage-crap4j=' => null, 43 'coverage-html=' => null, 44 'coverage-php=' => null, 45 'coverage-text==' => null, 46 'coverage-xml=' => null, 47 'debug' => null, 48 'exclude-group=' => null, 49 'filter=' => null, 50 'testsuite=' => null, 51 'group=' => null, 52 'help' => null, 53 'include-path=' => null, 54 'list-groups' => null, 55 'loader=' => null, 56 'log-json=' => null, 57 'log-junit=' => null, 58 'log-tap=' => null, 59 'process-isolation' => null, 60 'repeat=' => null, 61 'stderr' => null, 62 'stop-on-error' => null, 63 'stop-on-failure' => null, 64 'stop-on-incomplete' => null, 65 'stop-on-risky' => null, 66 'stop-on-skipped' => null, 67 'report-useless-tests' => null, 68 'strict-coverage' => null, 69 'disallow-test-output' => null, 70 'enforce-time-limit' => null, 71 'disallow-todo-tests' => null, 72 'strict-global-state' => null, 73 'strict' => null, 74 'tap' => null, 75 'testdox' => null, 76 'testdox-html=' => null, 77 'testdox-text=' => null, 78 'test-suffix=' => null, 79 'no-configuration' => null, 80 'no-coverage' => null, 81 'no-globals-backup' => null, 82 'printer=' => null, 83 'static-backup' => null, 84 'verbose' => null, 85 'version' => null 86 ); 87 88 /** 89 * @var bool 90 */ 91 private $versionStringPrinted = false; 92 93 /** 94 * @param bool $exit 95 */ 96 public static function main($exit = true) 97 { 98 $command = new static; 99 100 return $command->run($_SERVER['argv'], $exit); 101 } 102 103 /** 104 * @param array $argv 105 * @param bool $exit 106 * 107 * @return int 108 */ 109 public function run(array $argv, $exit = true) 110 { 111 $this->handleArguments($argv); 112 113 $runner = $this->createRunner(); 114 115 if (is_object($this->arguments['test']) && 116 $this->arguments['test'] instanceof PHPUnit_Framework_Test) { 117 $suite = $this->arguments['test']; 118 } else { 119 $suite = $runner->getTest( 120 $this->arguments['test'], 121 $this->arguments['testFile'], 122 $this->arguments['testSuffixes'] 123 ); 124 } 125 126 if ($this->arguments['listGroups']) { 127 $this->printVersionString(); 128 129 print "Available test group(s):\n"; 130 131 $groups = $suite->getGroups(); 132 sort($groups); 133 134 foreach ($groups as $group) { 135 print " - $group\n"; 136 } 137 138 if ($exit) { 139 exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); 140 } else { 141 return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT; 142 } 143 } 144 145 unset($this->arguments['test']); 146 unset($this->arguments['testFile']); 147 148 try { 149 $result = $runner->doRun($suite, $this->arguments); 150 } catch (PHPUnit_Framework_Exception $e) { 151 print $e->getMessage() . "\n"; 152 } 153 154 $ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT; 155 156 if (isset($result) && $result->wasSuccessful()) { 157 $ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT; 158 } elseif (!isset($result) || $result->errorCount() > 0) { 159 $ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT; 160 } 161 162 if ($exit) { 163 exit($ret); 164 } else { 165 return $ret; 166 } 167 } 168 169 /** 170 * Create a TestRunner, override in subclasses. 171 * 172 * @return PHPUnit_TextUI_TestRunner 173 * 174 * @since Method available since Release 3.6.0 175 */ 176 protected function createRunner() 177 { 178 return new PHPUnit_TextUI_TestRunner($this->arguments['loader']); 179 } 180 181 /** 182 * Handles the command-line arguments. 183 * 184 * A child class of PHPUnit_TextUI_Command can hook into the argument 185 * parsing by adding the switch(es) to the $longOptions array and point to a 186 * callback method that handles the switch(es) in the child class like this 187 * 188 * <code> 189 * <?php 190 * class MyCommand extends PHPUnit_TextUI_Command 191 * { 192 * public function __construct() 193 * { 194 * // my-switch won't accept a value, it's an on/off 195 * $this->longOptions['my-switch'] = 'myHandler'; 196 * // my-secondswitch will accept a value - note the equals sign 197 * $this->longOptions['my-secondswitch='] = 'myOtherHandler'; 198 * } 199 * 200 * // --my-switch -> myHandler() 201 * protected function myHandler() 202 * { 203 * } 204 * 205 * // --my-secondswitch foo -> myOtherHandler('foo') 206 * protected function myOtherHandler ($value) 207 * { 208 * } 209 * 210 * // You will also need this - the static keyword in the 211 * // PHPUnit_TextUI_Command will mean that it'll be 212 * // PHPUnit_TextUI_Command that gets instantiated, 213 * // not MyCommand 214 * public static function main($exit = true) 215 * { 216 * $command = new static; 217 * 218 * return $command->run($_SERVER['argv'], $exit); 219 * } 220 * 221 * } 222 * </code> 223 * 224 * @param array $argv 225 */ 226 protected function handleArguments(array $argv) 227 { 228 if (defined('__PHPUNIT_PHAR__')) { 229 $this->longOptions['check-version'] = null; 230 $this->longOptions['selfupdate'] = null; 231 $this->longOptions['self-update'] = null; 232 $this->longOptions['selfupgrade'] = null; 233 $this->longOptions['self-upgrade'] = null; 234 } 235 236 try { 237 $this->options = PHPUnit_Util_Getopt::getopt( 238 $argv, 239 'd:c:hv', 240 array_keys($this->longOptions) 241 ); 242 } catch (PHPUnit_Framework_Exception $e) { 243 $this->showError($e->getMessage()); 244 } 245 246 foreach ($this->options[0] as $option) { 247 switch ($option[0]) { 248 case '--colors': 249 $this->arguments['colors'] = $option[1] ?: PHPUnit_TextUI_ResultPrinter::COLOR_AUTO; 250 break; 251 252 case '--bootstrap': 253 $this->arguments['bootstrap'] = $option[1]; 254 break; 255 256 case '--columns': 257 if (is_numeric($option[1])) { 258 $this->arguments['columns'] = (int) $option[1]; 259 } elseif ($option[1] == 'max') { 260 $this->arguments['columns'] = 'max'; 261 } 262 break; 263 264 case 'c': 265 case '--configuration': 266 $this->arguments['configuration'] = $option[1]; 267 break; 268 269 case '--coverage-clover': 270 $this->arguments['coverageClover'] = $option[1]; 271 break; 272 273 case '--coverage-crap4j': 274 $this->arguments['coverageCrap4J'] = $option[1]; 275 break; 276 277 case '--coverage-html': 278 $this->arguments['coverageHtml'] = $option[1]; 279 break; 280 281 case '--coverage-php': 282 $this->arguments['coveragePHP'] = $option[1]; 283 break; 284 285 case '--coverage-text': 286 if ($option[1] === null) { 287 $option[1] = 'php://stdout'; 288 } 289 290 $this->arguments['coverageText'] = $option[1]; 291 $this->arguments['coverageTextShowUncoveredFiles'] = false; 292 $this->arguments['coverageTextShowOnlySummary'] = false; 293 break; 294 295 case '--coverage-xml': 296 $this->arguments['coverageXml'] = $option[1]; 297 break; 298 299 case 'd': 300 $ini = explode('=', $option[1]); 301 302 if (isset($ini[0])) { 303 if (isset($ini[1])) { 304 ini_set($ini[0], $ini[1]); 305 } else { 306 ini_set($ini[0], true); 307 } 308 } 309 break; 310 311 case '--debug': 312 $this->arguments['debug'] = true; 313 break; 314 315 case 'h': 316 case '--help': 317 $this->showHelp(); 318 exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); 319 break; 320 321 case '--filter': 322 $this->arguments['filter'] = $option[1]; 323 break; 324 325 case '--testsuite': 326 $this->arguments['testsuite'] = $option[1]; 327 break; 328 329 case '--group': 330 $this->arguments['groups'] = explode(',', $option[1]); 331 break; 332 333 case '--exclude-group': 334 $this->arguments['excludeGroups'] = explode( 335 ',', 336 $option[1] 337 ); 338 break; 339 340 case '--test-suffix': 341 $this->arguments['testSuffixes'] = explode( 342 ',', 343 $option[1] 344 ); 345 break; 346 347 case '--include-path': 348 $includePath = $option[1]; 349 break; 350 351 case '--list-groups': 352 $this->arguments['listGroups'] = true; 353 break; 354 355 case '--printer': 356 $this->arguments['printer'] = $option[1]; 357 break; 358 359 case '--loader': 360 $this->arguments['loader'] = $option[1]; 361 break; 362 363 case '--log-json': 364 $this->arguments['jsonLogfile'] = $option[1]; 365 break; 366 367 case '--log-junit': 368 $this->arguments['junitLogfile'] = $option[1]; 369 break; 370 371 case '--log-tap': 372 $this->arguments['tapLogfile'] = $option[1]; 373 break; 374 375 case '--process-isolation': 376 $this->arguments['processIsolation'] = true; 377 break; 378 379 case '--repeat': 380 $this->arguments['repeat'] = (int) $option[1]; 381 break; 382 383 case '--stderr': 384 $this->arguments['stderr'] = true; 385 break; 386 387 case '--stop-on-error': 388 $this->arguments['stopOnError'] = true; 389 break; 390 391 case '--stop-on-failure': 392 $this->arguments['stopOnFailure'] = true; 393 break; 394 395 case '--stop-on-incomplete': 396 $this->arguments['stopOnIncomplete'] = true; 397 break; 398 399 case '--stop-on-risky': 400 $this->arguments['stopOnRisky'] = true; 401 break; 402 403 case '--stop-on-skipped': 404 $this->arguments['stopOnSkipped'] = true; 405 break; 406 407 case '--tap': 408 $this->arguments['printer'] = 'PHPUnit_Util_Log_TAP'; 409 break; 410 411 case '--testdox': 412 $this->arguments['printer'] = 'PHPUnit_Util_TestDox_ResultPrinter_Text'; 413 break; 414 415 case '--testdox-html': 416 $this->arguments['testdoxHTMLFile'] = $option[1]; 417 break; 418 419 case '--testdox-text': 420 $this->arguments['testdoxTextFile'] = $option[1]; 421 break; 422 423 case '--no-configuration': 424 $this->arguments['useDefaultConfiguration'] = false; 425 break; 426 427 case '--no-coverage': 428 $this->arguments['noCoverage'] = true; 429 break; 430 431 case '--no-globals-backup': 432 $this->arguments['backupGlobals'] = false; 433 break; 434 435 case '--static-backup': 436 $this->arguments['backupStaticAttributes'] = true; 437 break; 438 439 case 'v': 440 case '--verbose': 441 $this->arguments['verbose'] = true; 442 break; 443 444 case '--version': 445 $this->printVersionString(); 446 exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); 447 break; 448 449 case '--report-useless-tests': 450 $this->arguments['reportUselessTests'] = true; 451 break; 452 453 case '--strict-coverage': 454 $this->arguments['strictCoverage'] = true; 455 break; 456 457 case '--strict-global-state': 458 $this->arguments['disallowChangesToGlobalState'] = true; 459 break; 460 461 case '--disallow-test-output': 462 $this->arguments['disallowTestOutput'] = true; 463 break; 464 465 case '--enforce-time-limit': 466 $this->arguments['enforceTimeLimit'] = true; 467 break; 468 469 case '--disallow-todo-tests': 470 $this->arguments['disallowTodoAnnotatedTests'] = true; 471 break; 472 473 case '--strict': 474 $this->arguments['reportUselessTests'] = true; 475 $this->arguments['strictCoverage'] = true; 476 $this->arguments['disallowTestOutput'] = true; 477 $this->arguments['enforceTimeLimit'] = true; 478 $this->arguments['disallowTodoAnnotatedTests'] = true; 479 $this->arguments['deprecatedStrictModeOption'] = true; 480 break; 481 482 case '--check-version': 483 $this->handleVersionCheck(); 484 break; 485 486 case '--selfupdate': 487 case '--self-update': 488 $this->handleSelfUpdate(); 489 break; 490 491 case '--selfupgrade': 492 case '--self-upgrade': 493 $this->handleSelfUpdate(true); 494 break; 495 496 case '--whitelist': 497 $this->arguments['whitelist'] = $option[1]; 498 break; 499 500 default: 501 $optionName = str_replace('--', '', $option[0]); 502 503 if (isset($this->longOptions[$optionName])) { 504 $handler = $this->longOptions[$optionName]; 505 } elseif (isset($this->longOptions[$optionName . '='])) { 506 $handler = $this->longOptions[$optionName . '=']; 507 } 508 509 if (isset($handler) && is_callable(array($this, $handler))) { 510 $this->$handler($option[1]); 511 } 512 } 513 } 514 515 $this->handleCustomTestSuite(); 516 517 if (!isset($this->arguments['test'])) { 518 if (isset($this->options[1][0])) { 519 $this->arguments['test'] = $this->options[1][0]; 520 } 521 522 if (isset($this->options[1][1])) { 523 $this->arguments['testFile'] = realpath($this->options[1][1]); 524 } else { 525 $this->arguments['testFile'] = ''; 526 } 527 528 if (isset($this->arguments['test']) && 529 is_file($this->arguments['test']) && 530 substr($this->arguments['test'], -5, 5) != '.phpt') { 531 $this->arguments['testFile'] = realpath($this->arguments['test']); 532 $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.')); 533 } 534 } 535 536 if (!isset($this->arguments['testSuffixes'])) { 537 $this->arguments['testSuffixes'] = array('Test.php', '.phpt'); 538 } 539 540 if (isset($includePath)) { 541 ini_set( 542 'include_path', 543 $includePath . PATH_SEPARATOR . ini_get('include_path') 544 ); 545 } 546 547 if ($this->arguments['loader'] !== null) { 548 $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); 549 } 550 551 if (isset($this->arguments['configuration']) && 552 is_dir($this->arguments['configuration'])) { 553 $configurationFile = $this->arguments['configuration'] . '/phpunit.xml'; 554 555 if (file_exists($configurationFile)) { 556 $this->arguments['configuration'] = realpath( 557 $configurationFile 558 ); 559 } elseif (file_exists($configurationFile . '.dist')) { 560 $this->arguments['configuration'] = realpath( 561 $configurationFile . '.dist' 562 ); 563 } 564 } elseif (!isset($this->arguments['configuration']) && 565 $this->arguments['useDefaultConfiguration']) { 566 if (file_exists('phpunit.xml')) { 567 $this->arguments['configuration'] = realpath('phpunit.xml'); 568 } elseif (file_exists('phpunit.xml.dist')) { 569 $this->arguments['configuration'] = realpath( 570 'phpunit.xml.dist' 571 ); 572 } 573 } 574 575 if (isset($this->arguments['configuration'])) { 576 try { 577 $configuration = PHPUnit_Util_Configuration::getInstance( 578 $this->arguments['configuration'] 579 ); 580 } catch (Throwable $e) { 581 print $e->getMessage() . "\n"; 582 exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); 583 } catch (Exception $e) { 584 print $e->getMessage() . "\n"; 585 exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); 586 } 587 588 $phpunit = $configuration->getPHPUnitConfiguration(); 589 590 $configuration->handlePHPConfiguration(); 591 592 /* 593 * Issue #1216 594 */ 595 if (isset($this->arguments['bootstrap'])) { 596 $this->handleBootstrap($this->arguments['bootstrap']); 597 } elseif (isset($phpunit['bootstrap'])) { 598 $this->handleBootstrap($phpunit['bootstrap']); 599 } 600 601 /* 602 * Issue #657 603 */ 604 if (isset($phpunit['stderr']) && ! isset($this->arguments['stderr'])) { 605 $this->arguments['stderr'] = $phpunit['stderr']; 606 } 607 608 if (isset($phpunit['columns']) && ! isset($this->arguments['columns'])) { 609 $this->arguments['columns'] = $phpunit['columns']; 610 } 611 612 if (isset($phpunit['printerClass'])) { 613 if (isset($phpunit['printerFile'])) { 614 $file = $phpunit['printerFile']; 615 } else { 616 $file = ''; 617 } 618 619 $this->arguments['printer'] = $this->handlePrinter( 620 $phpunit['printerClass'], 621 $file 622 ); 623 } 624 625 if (isset($phpunit['testSuiteLoaderClass'])) { 626 if (isset($phpunit['testSuiteLoaderFile'])) { 627 $file = $phpunit['testSuiteLoaderFile']; 628 } else { 629 $file = ''; 630 } 631 632 $this->arguments['loader'] = $this->handleLoader( 633 $phpunit['testSuiteLoaderClass'], 634 $file 635 ); 636 } 637 638 $browsers = $configuration->getSeleniumBrowserConfiguration(); 639 640 if (!empty($browsers)) { 641 $this->arguments['deprecatedSeleniumConfiguration'] = true; 642 643 if (class_exists('PHPUnit_Extensions_SeleniumTestCase')) { 644 PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; 645 } 646 } 647 648 if (!isset($this->arguments['test'])) { 649 $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null); 650 651 if ($testSuite !== null) { 652 $this->arguments['test'] = $testSuite; 653 } 654 } 655 } elseif (isset($this->arguments['bootstrap'])) { 656 $this->handleBootstrap($this->arguments['bootstrap']); 657 } 658 659 if (isset($this->arguments['printer']) && 660 is_string($this->arguments['printer'])) { 661 $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']); 662 } 663 664 if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') { 665 $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']); 666 667 $this->arguments['test'] = new PHPUnit_Framework_TestSuite; 668 $this->arguments['test']->addTest($test); 669 } 670 671 if (!isset($this->arguments['test']) || 672 (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) { 673 $this->showHelp(); 674 exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); 675 } 676 } 677 678 /** 679 * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation. 680 * 681 * @param string $loaderClass 682 * @param string $loaderFile 683 * 684 * @return PHPUnit_Runner_TestSuiteLoader 685 */ 686 protected function handleLoader($loaderClass, $loaderFile = '') 687 { 688 if (!class_exists($loaderClass, false)) { 689 if ($loaderFile == '') { 690 $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename( 691 $loaderClass 692 ); 693 } 694 695 $loaderFile = stream_resolve_include_path($loaderFile); 696 697 if ($loaderFile) { 698 require $loaderFile; 699 } 700 } 701 702 if (class_exists($loaderClass, false)) { 703 $class = new ReflectionClass($loaderClass); 704 705 if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') && 706 $class->isInstantiable()) { 707 return $class->newInstance(); 708 } 709 } 710 711 if ($loaderClass == 'PHPUnit_Runner_StandardTestSuiteLoader') { 712 return; 713 } 714 715 $this->showError( 716 sprintf( 717 'Could not use "%s" as loader.', 718 $loaderClass 719 ) 720 ); 721 } 722 723 /** 724 * Handles the loading of the PHPUnit_Util_Printer implementation. 725 * 726 * @param string $printerClass 727 * @param string $printerFile 728 * 729 * @return PHPUnit_Util_Printer 730 */ 731 protected function handlePrinter($printerClass, $printerFile = '') 732 { 733 if (!class_exists($printerClass, false)) { 734 if ($printerFile == '') { 735 $printerFile = PHPUnit_Util_Filesystem::classNameToFilename( 736 $printerClass 737 ); 738 } 739 740 $printerFile = stream_resolve_include_path($printerFile); 741 742 if ($printerFile) { 743 require $printerFile; 744 } 745 } 746 747 if (class_exists($printerClass)) { 748 $class = new ReflectionClass($printerClass); 749 750 if ($class->implementsInterface('PHPUnit_Framework_TestListener') && 751 $class->isSubclassOf('PHPUnit_Util_Printer') && 752 $class->isInstantiable()) { 753 if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) { 754 return $printerClass; 755 } 756 757 $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null; 758 759 return $class->newInstance($outputStream); 760 } 761 } 762 763 $this->showError( 764 sprintf( 765 'Could not use "%s" as printer.', 766 $printerClass 767 ) 768 ); 769 } 770 771 /** 772 * Loads a bootstrap file. 773 * 774 * @param string $filename 775 */ 776 protected function handleBootstrap($filename) 777 { 778 try { 779 PHPUnit_Util_Fileloader::checkAndLoad($filename); 780 } catch (PHPUnit_Framework_Exception $e) { 781 $this->showError($e->getMessage()); 782 } 783 } 784 785 /** 786 * @since Method available since Release 4.0.0 787 */ 788 protected function handleSelfUpdate($upgrade = false) 789 { 790 $this->printVersionString(); 791 792 $localFilename = realpath($_SERVER['argv'][0]); 793 794 if (!is_writable($localFilename)) { 795 print 'No write permission to update ' . $localFilename . "\n"; 796 exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); 797 } 798 799 if (!extension_loaded('openssl')) { 800 print "The OpenSSL extension is not loaded.\n"; 801 exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); 802 } 803 804 if (!$upgrade) { 805 $remoteFilename = sprintf( 806 'https://phar.phpunit.de/phpunit-%s.phar', 807 file_get_contents( 808 sprintf( 809 'https://phar.phpunit.de/latest-version-of/phpunit-%s', 810 PHPUnit_Runner_Version::series() 811 ) 812 ) 813 ); 814 } else { 815 $remoteFilename = sprintf( 816 'https://phar.phpunit.de/phpunit%s.phar', 817 PHPUnit_Runner_Version::getReleaseChannel() 818 ); 819 } 820 821 $tempFilename = tempnam(sys_get_temp_dir(), 'phpunit') . '.phar'; 822 823 // Workaround for https://bugs.php.net/bug.php?id=65538 824 $caFile = dirname($tempFilename) . '/ca.pem'; 825 copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile); 826 827 print 'Updating the PHPUnit PHAR ... '; 828 829 $options = array( 830 'ssl' => array( 831 'allow_self_signed' => false, 832 'cafile' => $caFile, 833 'verify_peer' => true 834 ) 835 ); 836 837 if (PHP_VERSION_ID < 50600) { 838 $options['ssl']['CN_match'] = 'phar.phpunit.de'; 839 $options['ssl']['SNI_server_name'] = 'phar.phpunit.de'; 840 } 841 842 file_put_contents( 843 $tempFilename, 844 file_get_contents( 845 $remoteFilename, 846 false, 847 stream_context_create($options) 848 ) 849 ); 850 851 chmod($tempFilename, 0777 & ~umask()); 852 853 try { 854 $phar = new Phar($tempFilename); 855 unset($phar); 856 rename($tempFilename, $localFilename); 857 unlink($caFile); 858 } catch (Throwable $_e) { 859 $e = $_e; 860 } catch (Exception $_e) { 861 $e = $_e; 862 } 863 864 if (isset($e)) { 865 unlink($caFile); 866 unlink($tempFilename); 867 print " done\n\n" . $e->getMessage() . "\n"; 868 exit(2); 869 } 870 871 print " done\n"; 872 exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); 873 } 874 875 /** 876 * @since Method available since Release 4.8.0 877 */ 878 protected function handleVersionCheck() 879 { 880 $this->printVersionString(); 881 882 $latestVersion = file_get_contents('https://phar.phpunit.de/latest-version-of/phpunit'); 883 $isOutdated = version_compare($latestVersion, PHPUnit_Runner_Version::id(), '>'); 884 885 if ($isOutdated) { 886 print "You are not using the latest version of PHPUnit.\n"; 887 print 'Use "phpunit --self-upgrade" to install PHPUnit ' . $latestVersion . "\n"; 888 } else { 889 print "You are using the latest version of PHPUnit.\n"; 890 } 891 892 exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); 893 } 894 895 /** 896 * Show the help message. 897 */ 898 protected function showHelp() 899 { 900 $this->printVersionString(); 901 902 print <<<EOT 903 Usage: phpunit [options] UnitTest [UnitTest.php] 904 phpunit [options] <directory> 905 906 Code Coverage Options: 907 908 --coverage-clover <file> Generate code coverage report in Clover XML format. 909 --coverage-crap4j <file> Generate code coverage report in Crap4J XML format. 910 --coverage-html <dir> Generate code coverage report in HTML format. 911 --coverage-php <file> Export PHP_CodeCoverage object to file. 912 --coverage-text=<file> Generate code coverage report in text format. 913 Default: Standard output. 914 --coverage-xml <dir> Generate code coverage report in PHPUnit XML format. 915 916 Logging Options: 917 918 --log-junit <file> Log test execution in JUnit XML format to file. 919 --log-tap <file> Log test execution in TAP format to file. 920 --log-json <file> Log test execution in JSON format. 921 --testdox-html <file> Write agile documentation in HTML format to file. 922 --testdox-text <file> Write agile documentation in Text format to file. 923 924 Test Selection Options: 925 926 --filter <pattern> Filter which tests to run. 927 --testsuite <pattern> Filter which testsuite to run. 928 --group ... Only runs tests from the specified group(s). 929 --exclude-group ... Exclude tests from the specified group(s). 930 --list-groups List available test groups. 931 --test-suffix ... Only search for test in files with specified 932 suffix(es). Default: Test.php,.phpt 933 934 Test Execution Options: 935 936 --report-useless-tests Be strict about tests that do not test anything. 937 --strict-coverage Be strict about unintentionally covered code. 938 --strict-global-state Be strict about changes to global state 939 --disallow-test-output Be strict about output during tests. 940 --enforce-time-limit Enforce time limit based on test size. 941 --disallow-todo-tests Disallow @todo-annotated tests. 942 943 --process-isolation Run each test in a separate PHP process. 944 --no-globals-backup Do not backup and restore \$GLOBALS for each test. 945 --static-backup Backup and restore static attributes for each test. 946 947 --colors=<flag> Use colors in output ("never", "auto" or "always"). 948 --columns <n> Number of columns to use for progress output. 949 --columns max Use maximum number of columns for progress output. 950 --stderr Write to STDERR instead of STDOUT. 951 --stop-on-error Stop execution upon first error. 952 --stop-on-failure Stop execution upon first error or failure. 953 --stop-on-risky Stop execution upon first risky test. 954 --stop-on-skipped Stop execution upon first skipped test. 955 --stop-on-incomplete Stop execution upon first incomplete test. 956 -v|--verbose Output more verbose information. 957 --debug Display debugging information during test execution. 958 959 --loader <loader> TestSuiteLoader implementation to use. 960 --repeat <times> Runs the test(s) repeatedly. 961 --tap Report test execution progress in TAP format. 962 --testdox Report test execution progress in TestDox format. 963 --printer <printer> TestListener implementation to use. 964 965 Configuration Options: 966 967 --bootstrap <file> A "bootstrap" PHP file that is run before the tests. 968 -c|--configuration <file> Read configuration from XML file. 969 --no-configuration Ignore default configuration file (phpunit.xml). 970 --no-coverage Ignore code coverage configuration. 971 --include-path <path(s)> Prepend PHP's include_path with given path(s). 972 -d key[=value] Sets a php.ini value. 973 974 Miscellaneous Options: 975 976 -h|--help Prints this usage information. 977 --version Prints the version and exits. 978 979 EOT; 980 981 if (defined('__PHPUNIT_PHAR__')) { 982 print "\n --check-version Check whether PHPUnit is the latest version."; 983 print "\n --self-update Update PHPUnit to the latest version within the same\n release series.\n"; 984 print "\n --self-upgrade Upgrade PHPUnit to the latest version.\n"; 985 } 986 } 987 988 /** 989 * Custom callback for test suite discovery. 990 */ 991 protected function handleCustomTestSuite() 992 { 993 } 994 995 private function printVersionString() 996 { 997 if ($this->versionStringPrinted) { 998 return; 999 } 1000 1001 print PHPUnit_Runner_Version::getVersionString() . "\n\n"; 1002 1003 $this->versionStringPrinted = true; 1004 } 1005 1006 /** 1007 */ 1008 private function showError($message) 1009 { 1010 $this->printVersionString(); 1011 1012 print $message . "\n"; 1013 1014 exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); 1015 } 1016 }