PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phpunit/phpunit/PHPUnit/TextUI/Command.php

https://bitbucket.org/alexpozdnyakov/kohana
PHP | 897 lines | 620 code | 140 blank | 137 comment | 90 complexity | 9aec0949e2aa6a08d49f2de4b5fe576e MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * PHPUnit
  4. *
  5. * Copyright (c) 2001-2012, Sebastian Bergmann <sebastian@phpunit.de>.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * * Neither the name of Sebastian Bergmann nor the names of his
  21. * contributors may be used to endorse or promote products derived
  22. * from this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  28. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  29. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  30. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  32. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  34. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. * POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. * @package PHPUnit
  38. * @subpackage TextUI
  39. * @author Sebastian Bergmann <sebastian@phpunit.de>
  40. * @copyright 2001-2012 Sebastian Bergmann <sebastian@phpunit.de>
  41. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  42. * @link http://www.phpunit.de/
  43. * @since File available since Release 3.0.0
  44. */
  45. /**
  46. * A TestRunner for the Command Line Interface (CLI)
  47. * PHP SAPI Module.
  48. *
  49. * @package PHPUnit
  50. * @subpackage TextUI
  51. * @author Sebastian Bergmann <sebastian@phpunit.de>
  52. * @copyright 2001-2012 Sebastian Bergmann <sebastian@phpunit.de>
  53. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  54. * @link http://www.phpunit.de/
  55. * @since Class available since Release 3.0.0
  56. */
  57. class PHPUnit_TextUI_Command
  58. {
  59. /**
  60. * @var array
  61. */
  62. protected $arguments = array(
  63. 'listGroups' => FALSE,
  64. 'loader' => NULL,
  65. 'useDefaultConfiguration' => TRUE
  66. );
  67. /**
  68. * @var array
  69. */
  70. protected $options = array();
  71. /**
  72. * @var array
  73. */
  74. protected $longOptions = array(
  75. 'colors' => NULL,
  76. 'bootstrap=' => NULL,
  77. 'configuration=' => NULL,
  78. 'coverage-html=' => NULL,
  79. 'coverage-clover=' => NULL,
  80. 'coverage-php=' => NULL,
  81. 'coverage-text==' => NULL,
  82. 'debug' => NULL,
  83. 'exclude-group=' => NULL,
  84. 'filter=' => NULL,
  85. 'testsuite=' => NULL,
  86. 'group=' => NULL,
  87. 'help' => NULL,
  88. 'include-path=' => NULL,
  89. 'list-groups' => NULL,
  90. 'loader=' => NULL,
  91. 'log-json=' => NULL,
  92. 'log-junit=' => NULL,
  93. 'log-tap=' => NULL,
  94. 'process-isolation' => NULL,
  95. 'repeat=' => NULL,
  96. 'stderr' => NULL,
  97. 'stop-on-error' => NULL,
  98. 'stop-on-failure' => NULL,
  99. 'stop-on-incomplete' => NULL,
  100. 'stop-on-skipped' => NULL,
  101. 'strict' => NULL,
  102. 'tap' => NULL,
  103. 'testdox' => NULL,
  104. 'testdox-html=' => NULL,
  105. 'testdox-text=' => NULL,
  106. 'test-suffix=' => NULL,
  107. 'no-configuration' => NULL,
  108. 'no-globals-backup' => NULL,
  109. 'printer=' => NULL,
  110. 'static-backup' => NULL,
  111. 'verbose' => NULL,
  112. 'version' => NULL
  113. );
  114. /**
  115. * @var array
  116. */
  117. protected $missingExtensions = array();
  118. /**
  119. * @param boolean $exit
  120. */
  121. public static function main($exit = TRUE)
  122. {
  123. $command = new PHPUnit_TextUI_Command;
  124. return $command->run($_SERVER['argv'], $exit);
  125. }
  126. /**
  127. * @param array $argv
  128. * @param boolean $exit
  129. */
  130. public function run(array $argv, $exit = TRUE)
  131. {
  132. $this->handleArguments($argv);
  133. $runner = $this->createRunner();
  134. if (is_object($this->arguments['test']) &&
  135. $this->arguments['test'] instanceof PHPUnit_Framework_Test) {
  136. $suite = $this->arguments['test'];
  137. } else {
  138. $suite = $runner->getTest(
  139. $this->arguments['test'],
  140. $this->arguments['testFile'],
  141. $this->arguments['testSuffixes']
  142. );
  143. }
  144. if ($this->arguments['listGroups']) {
  145. PHPUnit_TextUI_TestRunner::printVersionString();
  146. print "Available test group(s):\n";
  147. $groups = $suite->getGroups();
  148. sort($groups);
  149. foreach ($groups as $group) {
  150. print " - $group\n";
  151. }
  152. if ($exit) {
  153. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  154. } else {
  155. return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  156. }
  157. }
  158. unset($this->arguments['test']);
  159. unset($this->arguments['testFile']);
  160. try {
  161. $result = $runner->doRun($suite, $this->arguments);
  162. }
  163. catch (PHPUnit_Framework_Exception $e) {
  164. print $e->getMessage() . "\n";
  165. }
  166. $ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT;
  167. if (isset($result) && $result->wasSuccessful()) {
  168. $ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  169. }
  170. else if (!isset($result) || $result->errorCount() > 0) {
  171. $ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT;
  172. }
  173. if ($exit) {
  174. exit($ret);
  175. } else {
  176. return $ret;
  177. }
  178. }
  179. /**
  180. * Create a TestRunner, override in subclasses.
  181. *
  182. * @return PHPUnit_TextUI_TestRunner
  183. * @since Method available since Release 3.6.0
  184. */
  185. protected function createRunner()
  186. {
  187. return new PHPUnit_TextUI_TestRunner($this->arguments['loader']);
  188. }
  189. /**
  190. * Handles the command-line arguments.
  191. *
  192. * A child class of PHPUnit_TextUI_Command can hook into the argument
  193. * parsing by adding the switch(es) to the $longOptions array and point to a
  194. * callback method that handles the switch(es) in the child class like this
  195. *
  196. * <code>
  197. * <?php
  198. * class MyCommand extends PHPUnit_TextUI_Command
  199. * {
  200. * public function __construct()
  201. * {
  202. * $this->longOptions['--my-switch'] = 'myHandler';
  203. * }
  204. *
  205. * // --my-switch foo -> myHandler('foo')
  206. * protected function myHandler($value)
  207. * {
  208. * }
  209. * }
  210. * </code>
  211. *
  212. * @param array $argv
  213. */
  214. protected function handleArguments(array $argv)
  215. {
  216. try {
  217. $this->options = PHPUnit_Util_Getopt::getopt(
  218. $argv,
  219. 'd:c:hv',
  220. array_keys($this->longOptions)
  221. );
  222. }
  223. catch (PHPUnit_Framework_Exception $e) {
  224. PHPUnit_TextUI_TestRunner::showError($e->getMessage());
  225. }
  226. foreach ($this->options[0] as $option) {
  227. switch ($option[0]) {
  228. case '--colors': {
  229. $this->arguments['colors'] = TRUE;
  230. }
  231. break;
  232. case '--bootstrap': {
  233. $this->arguments['bootstrap'] = $option[1];
  234. }
  235. break;
  236. case 'c':
  237. case '--configuration': {
  238. $this->arguments['configuration'] = $option[1];
  239. }
  240. break;
  241. case '--coverage-clover':
  242. case '--coverage-html':
  243. case '--coverage-php':
  244. case '--coverage-text': {
  245. if (!extension_loaded('tokenizer')) {
  246. $this->showExtensionNotLoadedMessage(
  247. 'tokenizer', 'No code coverage will be generated.'
  248. );
  249. continue;
  250. }
  251. if (!extension_loaded('xdebug')) {
  252. $this->showExtensionNotLoadedMessage(
  253. 'Xdebug', 'No code coverage will be generated.'
  254. );
  255. continue;
  256. }
  257. switch ($option[0]) {
  258. case '--coverage-clover': {
  259. $this->arguments['coverageClover'] = $option[1];
  260. }
  261. break;
  262. case '--coverage-html': {
  263. $this->arguments['reportDirectory'] = $option[1];
  264. }
  265. break;
  266. case '--coverage-php': {
  267. $this->arguments['coveragePHP'] = $option[1];
  268. }
  269. break;
  270. case '--coverage-text': {
  271. if ($option[1] === NULL) {
  272. $option[1] = 'php://stdout';
  273. }
  274. $this->arguments['coverageText'] = $option[1];
  275. $this->arguments['coverageTextShowUncoveredFiles'] = FALSE;
  276. }
  277. break;
  278. }
  279. }
  280. break;
  281. case 'd': {
  282. $ini = explode('=', $option[1]);
  283. if (isset($ini[0])) {
  284. if (isset($ini[1])) {
  285. ini_set($ini[0], $ini[1]);
  286. } else {
  287. ini_set($ini[0], TRUE);
  288. }
  289. }
  290. }
  291. break;
  292. case '--debug': {
  293. $this->arguments['debug'] = TRUE;
  294. }
  295. break;
  296. case 'h':
  297. case '--help': {
  298. $this->showHelp();
  299. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  300. }
  301. break;
  302. case '--filter': {
  303. $this->arguments['filter'] = $option[1];
  304. }
  305. break;
  306. case '--testsuite': {
  307. $this->arguments['testsuite'] = $option[1];
  308. }
  309. break;
  310. case '--group': {
  311. $this->arguments['groups'] = explode(',', $option[1]);
  312. }
  313. break;
  314. case '--exclude-group': {
  315. $this->arguments['excludeGroups'] = explode(
  316. ',', $option[1]
  317. );
  318. }
  319. break;
  320. case '--test-suffix': {
  321. $this->arguments['testSuffixes'] = explode(
  322. ',', $option[1]
  323. );
  324. }
  325. break;
  326. case '--include-path': {
  327. $includePath = $option[1];
  328. }
  329. break;
  330. case '--list-groups': {
  331. $this->arguments['listGroups'] = TRUE;
  332. }
  333. break;
  334. case '--printer': {
  335. $this->arguments['printer'] = $option[1];
  336. }
  337. break;
  338. case '--loader': {
  339. $this->arguments['loader'] = $option[1];
  340. }
  341. break;
  342. case '--log-json': {
  343. $this->arguments['jsonLogfile'] = $option[1];
  344. }
  345. break;
  346. case '--log-junit': {
  347. $this->arguments['junitLogfile'] = $option[1];
  348. }
  349. break;
  350. case '--log-tap': {
  351. $this->arguments['tapLogfile'] = $option[1];
  352. }
  353. break;
  354. case '--process-isolation': {
  355. $this->arguments['processIsolation'] = TRUE;
  356. }
  357. break;
  358. case '--repeat': {
  359. $this->arguments['repeat'] = (int)$option[1];
  360. }
  361. break;
  362. case '--stderr': {
  363. $this->arguments['printer'] = new PHPUnit_TextUI_ResultPrinter(
  364. 'php://stderr',
  365. isset($this->arguments['verbose']) ? $this->arguments['verbose'] : FALSE
  366. );
  367. }
  368. break;
  369. case '--stop-on-error': {
  370. $this->arguments['stopOnError'] = TRUE;
  371. }
  372. break;
  373. case '--stop-on-failure': {
  374. $this->arguments['stopOnFailure'] = TRUE;
  375. }
  376. break;
  377. case '--stop-on-incomplete': {
  378. $this->arguments['stopOnIncomplete'] = TRUE;
  379. }
  380. break;
  381. case '--stop-on-skipped': {
  382. $this->arguments['stopOnSkipped'] = TRUE;
  383. }
  384. break;
  385. case '--tap': {
  386. $this->arguments['printer'] = new PHPUnit_Util_Log_TAP;
  387. }
  388. break;
  389. case '--testdox': {
  390. $this->arguments['printer'] = new PHPUnit_Util_TestDox_ResultPrinter_Text;
  391. }
  392. break;
  393. case '--testdox-html': {
  394. $this->arguments['testdoxHTMLFile'] = $option[1];
  395. }
  396. break;
  397. case '--testdox-text': {
  398. $this->arguments['testdoxTextFile'] = $option[1];
  399. }
  400. break;
  401. case '--no-configuration': {
  402. $this->arguments['useDefaultConfiguration'] = FALSE;
  403. }
  404. break;
  405. case '--no-globals-backup': {
  406. $this->arguments['backupGlobals'] = FALSE;
  407. }
  408. break;
  409. case '--static-backup': {
  410. $this->arguments['backupStaticAttributes'] = TRUE;
  411. }
  412. break;
  413. case 'v':
  414. case '--verbose': {
  415. $this->arguments['verbose'] = TRUE;
  416. }
  417. break;
  418. case '--version': {
  419. PHPUnit_TextUI_TestRunner::printVersionString();
  420. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  421. }
  422. break;
  423. case '--strict': {
  424. $this->arguments['strict'] = TRUE;
  425. }
  426. break;
  427. default: {
  428. $optionName = str_replace('--', '', $option[0]);
  429. if (isset($this->longOptions[$optionName])) {
  430. $handler = $this->longOptions[$optionName];
  431. }
  432. else if (isset($this->longOptions[$optionName . '='])) {
  433. $handler = $this->longOptions[$optionName . '='];
  434. }
  435. if (isset($handler) && is_callable(array($this, $handler))) {
  436. $this->$handler($option[1]);
  437. }
  438. }
  439. }
  440. }
  441. $this->handleCustomTestSuite();
  442. if (!isset($this->arguments['test'])) {
  443. if (isset($this->options[1][0])) {
  444. $this->arguments['test'] = $this->options[1][0];
  445. }
  446. if (isset($this->options[1][1])) {
  447. $this->arguments['testFile'] = $this->options[1][1];
  448. } else {
  449. $this->arguments['testFile'] = '';
  450. }
  451. if (isset($this->arguments['test']) &&
  452. is_file($this->arguments['test']) &&
  453. substr($this->arguments['test'], -5, 5) != '.phpt') {
  454. $this->arguments['testFile'] = realpath($this->arguments['test']);
  455. $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.'));
  456. }
  457. }
  458. if (!isset($this->arguments['testSuffixes'])) {
  459. $this->arguments['testSuffixes'] = array('Test.php', '.phpt');
  460. }
  461. if (isset($includePath)) {
  462. ini_set(
  463. 'include_path',
  464. $includePath . PATH_SEPARATOR . ini_get('include_path')
  465. );
  466. }
  467. if (isset($this->arguments['bootstrap'])) {
  468. $this->handleBootstrap($this->arguments['bootstrap']);
  469. }
  470. if (isset($this->arguments['printer']) &&
  471. is_string($this->arguments['printer'])) {
  472. $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
  473. }
  474. if ($this->arguments['loader'] !== NULL) {
  475. $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
  476. }
  477. if (isset($this->arguments['configuration']) &&
  478. is_dir($this->arguments['configuration'])) {
  479. $configurationFile = $this->arguments['configuration'] .
  480. '/phpunit.xml';
  481. if (file_exists($configurationFile)) {
  482. $this->arguments['configuration'] = realpath(
  483. $configurationFile
  484. );
  485. }
  486. else if (file_exists($configurationFile . '.dist')) {
  487. $this->arguments['configuration'] = realpath(
  488. $configurationFile . '.dist'
  489. );
  490. }
  491. }
  492. else if (!isset($this->arguments['configuration']) &&
  493. $this->arguments['useDefaultConfiguration']) {
  494. if (file_exists('phpunit.xml')) {
  495. $this->arguments['configuration'] = realpath('phpunit.xml');
  496. } else if (file_exists('phpunit.xml.dist')) {
  497. $this->arguments['configuration'] = realpath(
  498. 'phpunit.xml.dist'
  499. );
  500. }
  501. }
  502. if (isset($this->arguments['configuration'])) {
  503. try {
  504. $configuration = PHPUnit_Util_Configuration::getInstance(
  505. $this->arguments['configuration']
  506. );
  507. }
  508. catch (Exception $e) {
  509. print $e->getMessage() . "\n";
  510. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  511. }
  512. $phpunit = $configuration->getPHPUnitConfiguration();
  513. $configuration->handlePHPConfiguration();
  514. if (!isset($this->arguments['bootstrap']) && isset($phpunit['bootstrap'])) {
  515. $this->handleBootstrap($phpunit['bootstrap']);
  516. }
  517. if (isset($phpunit['printerClass'])) {
  518. if (isset($phpunit['printerFile'])) {
  519. $file = $phpunit['printerFile'];
  520. } else {
  521. $file = '';
  522. }
  523. $this->arguments['printer'] = $this->handlePrinter(
  524. $phpunit['printerClass'], $file
  525. );
  526. }
  527. if (isset($phpunit['testSuiteLoaderClass'])) {
  528. if (isset($phpunit['testSuiteLoaderFile'])) {
  529. $file = $phpunit['testSuiteLoaderFile'];
  530. } else {
  531. $file = '';
  532. }
  533. $this->arguments['loader'] = $this->handleLoader(
  534. $phpunit['testSuiteLoaderClass'], $file
  535. );
  536. }
  537. $logging = $configuration->getLoggingConfiguration();
  538. if (isset($logging['coverage-html']) || isset($logging['coverage-clover']) || isset($logging['coverage-text']) ) {
  539. if (!extension_loaded('tokenizer')) {
  540. $this->showExtensionNotLoadedMessage(
  541. 'tokenizer', 'No code coverage will be generated.'
  542. );
  543. }
  544. else if (!extension_loaded('Xdebug')) {
  545. $this->showExtensionNotLoadedMessage(
  546. 'Xdebug', 'No code coverage will be generated.'
  547. );
  548. }
  549. }
  550. $browsers = $configuration->getSeleniumBrowserConfiguration();
  551. if (!empty($browsers) &&
  552. class_exists('PHPUnit_Extensions_SeleniumTestCase')) {
  553. PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers;
  554. }
  555. if (!isset($this->arguments['test'])) {
  556. $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null);
  557. if ($testSuite !== NULL) {
  558. $this->arguments['test'] = $testSuite;
  559. }
  560. }
  561. }
  562. if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') {
  563. $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']);
  564. $this->arguments['test'] = new PHPUnit_Framework_TestSuite;
  565. $this->arguments['test']->addTest($test);
  566. }
  567. if (!isset($this->arguments['test']) ||
  568. (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) {
  569. $this->showHelp();
  570. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  571. }
  572. }
  573. /**
  574. * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation.
  575. *
  576. * @param string $loaderClass
  577. * @param string $loaderFile
  578. * @return PHPUnit_Runner_TestSuiteLoader
  579. */
  580. protected function handleLoader($loaderClass, $loaderFile = '')
  581. {
  582. if (!class_exists($loaderClass, FALSE)) {
  583. if ($loaderFile == '') {
  584. $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename(
  585. $loaderClass
  586. );
  587. }
  588. $loaderFile = stream_resolve_include_path($loaderFile);
  589. if ($loaderFile) {
  590. require $loaderFile;
  591. }
  592. }
  593. if (class_exists($loaderClass, FALSE)) {
  594. $class = new ReflectionClass($loaderClass);
  595. if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') &&
  596. $class->isInstantiable()) {
  597. $loader = $class->newInstance();
  598. }
  599. }
  600. if (!isset($loader)) {
  601. PHPUnit_TextUI_TestRunner::showError(
  602. sprintf(
  603. 'Could not use "%s" as loader.',
  604. $loaderClass
  605. )
  606. );
  607. }
  608. return $loader;
  609. }
  610. /**
  611. * Handles the loading of the PHPUnit_Util_Printer implementation.
  612. *
  613. * @param string $printerClass
  614. * @param string $printerFile
  615. * @return PHPUnit_Util_Printer
  616. */
  617. protected function handlePrinter($printerClass, $printerFile = '')
  618. {
  619. if (!class_exists($printerClass, FALSE)) {
  620. if ($printerFile == '') {
  621. $printerFile = PHPUnit_Util_Filesystem::classNameToFilename(
  622. $printerClass
  623. );
  624. }
  625. $printerFile = stream_resolve_include_path($printerFile);
  626. if ($printerFile) {
  627. require $printerFile;
  628. }
  629. }
  630. if (class_exists($printerClass, FALSE)) {
  631. $class = new ReflectionClass($printerClass);
  632. if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
  633. $class->isSubclassOf('PHPUnit_Util_Printer') &&
  634. $class->isInstantiable()) {
  635. $printer = $class->newInstance();
  636. }
  637. }
  638. if (!isset($printer)) {
  639. PHPUnit_TextUI_TestRunner::showError(
  640. sprintf(
  641. 'Could not use "%s" as printer.',
  642. $printerClass
  643. )
  644. );
  645. }
  646. return $printer;
  647. }
  648. /**
  649. * Loads a bootstrap file.
  650. *
  651. * @param string $filename
  652. */
  653. protected function handleBootstrap($filename)
  654. {
  655. try {
  656. PHPUnit_Util_Fileloader::checkAndLoad($filename);
  657. }
  658. catch (PHPUnit_Framework_Exception $e) {
  659. PHPUnit_TextUI_TestRunner::showError($e->getMessage());
  660. }
  661. }
  662. /**
  663. * @param string $message
  664. * @since Method available since Release 3.6.0
  665. */
  666. protected function showExtensionNotLoadedMessage($extension, $message = '')
  667. {
  668. if (isset($this->missingExtensions[$extension])) {
  669. return;
  670. }
  671. if (!empty($message)) {
  672. $message = ' ' . $message;
  673. }
  674. $this->showMessage(
  675. 'The ' . $extension . ' extension is not loaded.' . $message . "\n",
  676. FALSE
  677. );
  678. $this->missingExtensions[$extension] = TRUE;
  679. }
  680. /**
  681. * Shows a message.
  682. *
  683. * @param string $message
  684. * @param boolean $exit
  685. */
  686. protected function showMessage($message, $exit = TRUE)
  687. {
  688. PHPUnit_TextUI_TestRunner::printVersionString();
  689. print $message . "\n";
  690. if ($exit) {
  691. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  692. } else {
  693. print "\n";
  694. }
  695. }
  696. /**
  697. * Show the help message.
  698. */
  699. protected function showHelp()
  700. {
  701. PHPUnit_TextUI_TestRunner::printVersionString();
  702. print <<<EOT
  703. Usage: phpunit [switches] UnitTest [UnitTest.php]
  704. phpunit [switches] <directory>
  705. --log-junit <file> Log test execution in JUnit XML format to file.
  706. --log-tap <file> Log test execution in TAP format to file.
  707. --log-json <file> Log test execution in JSON format.
  708. --coverage-clover <file> Generate code coverage report in Clover XML format.
  709. --coverage-html <dir> Generate code coverage report in HTML format.
  710. --coverage-php <file> Serialize PHP_CodeCoverage object to file.
  711. --coverage-text=<file> Generate code coverage report in text format.
  712. Default to writing to the standard output.
  713. --testdox-html <file> Write agile documentation in HTML format to file.
  714. --testdox-text <file> Write agile documentation in Text format to file.
  715. --filter <pattern> Filter which tests to run.
  716. --testsuite <pattern> Filter which testsuite to run.
  717. --group ... Only runs tests from the specified group(s).
  718. --exclude-group ... Exclude tests from the specified group(s).
  719. --list-groups List available test groups.
  720. --test-suffix ... Only search for test in files with specified
  721. suffix(es). Default: Test.php,.phpt
  722. --loader <loader> TestSuiteLoader implementation to use.
  723. --printer <printer> TestSuiteListener implementation to use.
  724. --repeat <times> Runs the test(s) repeatedly.
  725. --tap Report test execution progress in TAP format.
  726. --testdox Report test execution progress in TestDox format.
  727. --colors Use colors in output.
  728. --stderr Write to STDERR instead of STDOUT.
  729. --stop-on-error Stop execution upon first error.
  730. --stop-on-failure Stop execution upon first error or failure.
  731. --stop-on-skipped Stop execution upon first skipped test.
  732. --stop-on-incomplete Stop execution upon first incomplete test.
  733. --strict Run tests in strict mode.
  734. -v|--verbose Output more verbose information.
  735. --debug Display debugging information during test execution.
  736. --process-isolation Run each test in a separate PHP process.
  737. --no-globals-backup Do not backup and restore \$GLOBALS for each test.
  738. --static-backup Backup and restore static attributes for each test.
  739. --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
  740. -c|--configuration <file> Read configuration from XML file.
  741. --no-configuration Ignore default configuration file (phpunit.xml).
  742. --include-path <path(s)> Prepend PHP's include_path with given path(s).
  743. -d key[=value] Sets a php.ini value.
  744. -h|--help Prints this usage information.
  745. --version Prints the version and exits.
  746. EOT;
  747. }
  748. /**
  749. * Custom callback for test suite discovery.
  750. */
  751. protected function handleCustomTestSuite()
  752. {
  753. }
  754. }