PHPUnitTestRunner.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. /**
  3. * $Id: PHPUnitTestRunner.php 906 2010-10-05 18:01:43Z mrook $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. // phpunit 3.5 ships with autoloader
  22. // @todo - find out sane model for Phing and PHPUnit autoloaders/hooks co-existense
  23. if (version_compare(PHPUnit_Runner_Version::id(), '3.5.0') >=0) {
  24. require_once 'PHPUnit/Autoload.php';
  25. }
  26. require_once 'PHPUnit/Util/ErrorHandler.php';
  27. require_once 'PHPUnit/Util/Filter.php';
  28. require_once 'phing/tasks/ext/coverage/CoverageMerger.php';
  29. require_once 'phing/system/util/Timer.php';
  30. /**
  31. * Simple Testrunner for PHPUnit that runs all tests of a testsuite.
  32. *
  33. * @author Michiel Rook <michiel.rook@gmail.com>
  34. * @version $Id: PHPUnitTestRunner.php 906 2010-10-05 18:01:43Z mrook $
  35. * @package phing.tasks.ext.phpunit
  36. * @since 2.1.0
  37. */
  38. class PHPUnitTestRunner extends PHPUnit_Runner_BaseTestRunner implements PHPUnit_Framework_TestListener
  39. {
  40. const SUCCESS = 0;
  41. const FAILURES = 1;
  42. const ERRORS = 2;
  43. const INCOMPLETES = 3;
  44. const SKIPPED = 4;
  45. private $retCode = 0;
  46. private $lastFailureMessage = "";
  47. private $formatters = array();
  48. private $codecoverage = false;
  49. private $project = NULL;
  50. private $groups = array();
  51. private $excludeGroups = array();
  52. private $useCustomErrorHandler = true;
  53. public function __construct(Project $project, $groups = array(), $excludeGroups = array())
  54. {
  55. $this->project = $project;
  56. $this->groups = $groups;
  57. $this->excludeGroups = $excludeGroups;
  58. $this->retCode = self::SUCCESS;
  59. }
  60. public function setCodecoverage($codecoverage)
  61. {
  62. $this->codecoverage = $codecoverage;
  63. }
  64. public function setUseCustomErrorHandler($useCustomErrorHandler)
  65. {
  66. $this->useCustomErrorHandler = $useCustomErrorHandler;
  67. }
  68. public function addFormatter($formatter)
  69. {
  70. $this->formatters[] = $formatter;
  71. }
  72. public static function handleError($level, $message, $file, $line)
  73. {
  74. $isFiltered = false;
  75. if (version_compare(PHPUnit_Runner_Version::id(), '3.5.0') >=0) {
  76. $isFiltered = PHP_CodeCoverage::getInstance()->filter()->isFiltered(
  77. $file, array(), true
  78. );
  79. } else {
  80. $isFiltered = PHPUnit_Util_Filter::isFiltered($file, true, true);
  81. }
  82. if (!$isFiltered) {
  83. return PHPUnit_Util_ErrorHandler::handleError($level, $message, $file, $line);
  84. }
  85. }
  86. /**
  87. * Run a test
  88. */
  89. public function run(PHPUnit_Framework_TestSuite $suite)
  90. {
  91. $res = new PHPUnit_Framework_TestResult();
  92. if ($this->codecoverage)
  93. {
  94. $res->collectCodeCoverageInformation(TRUE);
  95. }
  96. $res->addListener($this);
  97. foreach ($this->formatters as $formatter)
  98. {
  99. $res->addListener($formatter);
  100. }
  101. /* Set PHPUnit error handler */
  102. if ($this->useCustomErrorHandler)
  103. {
  104. $oldErrorHandler = set_error_handler(array('PHPUnitTestRunner', 'handleError'), E_ALL | E_STRICT);
  105. }
  106. $suite->run($res, false, $this->groups, $this->excludeGroups);
  107. foreach ($this->formatters as $formatter)
  108. {
  109. $formatter->processResult($res);
  110. }
  111. /* Restore Phing error handler */
  112. if ($this->useCustomErrorHandler)
  113. {
  114. restore_error_handler();
  115. }
  116. if ($this->codecoverage)
  117. {
  118. $coverage = $res->getCodeCoverage();
  119. $summary = $coverage->getSummary();
  120. CoverageMerger::merge($this->project, $summary);
  121. }
  122. if ($res->errorCount() != 0)
  123. {
  124. $this->retCode = self::ERRORS;
  125. }
  126. else if ($res->failureCount() != 0)
  127. {
  128. $this->retCode = self::FAILURES;
  129. }
  130. else if ($res->notImplementedCount() != 0)
  131. {
  132. $this->retCode = self::INCOMPLETES;
  133. }
  134. else if ($res->skippedCount() != 0)
  135. {
  136. $this->retCode = self::SKIPPED;
  137. }
  138. }
  139. public function getRetCode()
  140. {
  141. return $this->retCode;
  142. }
  143. public function getLastFailureMessage()
  144. {
  145. return $this->lastFailureMessage;
  146. }
  147. /**
  148. * An error occurred.
  149. *
  150. * @param PHPUnit_Framework_Test $test
  151. * @param Exception $e
  152. * @param float $time
  153. */
  154. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  155. {
  156. $this->lastFailureMessage = "Test ERROR (" . $test->getName() . "): " . $e->getMessage();
  157. }
  158. /**
  159. * A failure occurred.
  160. *
  161. * @param PHPUnit_Framework_Test $test
  162. * @param PHPUnit_Framework_AssertionFailedError $e
  163. * @param float $time
  164. */
  165. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  166. {
  167. $this->lastFailureMessage = "Test FAILURE (" . $test->getName() . "): " . $e->getMessage();
  168. }
  169. /**
  170. * Incomplete test.
  171. *
  172. * @param PHPUnit_Framework_Test $test
  173. * @param Exception $e
  174. * @param float $time
  175. */
  176. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  177. {
  178. $this->lastFailureMessage = "Test INCOMPLETE (" . $test->getName() . "): " . $e->getMessage();
  179. }
  180. /**
  181. * Skipped test.
  182. *
  183. * @param PHPUnit_Framework_Test $test
  184. * @param Exception $e
  185. * @param float $time
  186. * @since Method available since Release 3.0.0
  187. */
  188. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  189. {
  190. $this->lastFailureMessage = "Test SKIPPED (" . $test->getName() . "): " . $e->getMessage();
  191. }
  192. /**
  193. * A test started.
  194. *
  195. * @param string $testName
  196. */
  197. public function testStarted($testName)
  198. {
  199. }
  200. /**
  201. * A test ended.
  202. *
  203. * @param string $testName
  204. */
  205. public function testEnded($testName)
  206. {
  207. }
  208. /**
  209. * A test failed.
  210. *
  211. * @param integer $status
  212. * @param PHPUnit_Framework_Test $test
  213. * @param PHPUnit_Framework_AssertionFailedError $e
  214. */
  215. public function testFailed($status, PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e)
  216. {
  217. }
  218. /**
  219. * Override to define how to handle a failed loading of
  220. * a test suite.
  221. *
  222. * @param string $message
  223. */
  224. protected function runFailed($message)
  225. {
  226. throw new BuildException($message);
  227. }
  228. /**
  229. * A test suite started.
  230. *
  231. * @param PHPUnit_Framework_TestSuite $suite
  232. * @since Method available since Release 2.2.0
  233. */
  234. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  235. {
  236. }
  237. /**
  238. * A test suite ended.
  239. *
  240. * @param PHPUnit_Framework_TestSuite $suite
  241. * @since Method available since Release 2.2.0
  242. */
  243. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  244. {
  245. }
  246. /**
  247. * A test started.
  248. *
  249. * @param PHPUnit_Framework_Test $test
  250. */
  251. public function startTest(PHPUnit_Framework_Test $test)
  252. {
  253. }
  254. /**
  255. * A test ended.
  256. *
  257. * @param PHPUnit_Framework_Test $test
  258. * @param float $time
  259. */
  260. public function endTest(PHPUnit_Framework_Test $test, $time)
  261. {
  262. }
  263. }