Prints the result of a TextUI TestRunner run.
@package PHPUnit @subpackage TextUI @author Sebastian Bergmann <sebastian@phpunit.de> @copyright 2001-2013 Sebastian Bergmann <sebastian@phpunit.de> @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License @link http://www.phpunit.de/ @since Class available since Release 2.0.0
Expanded class hierarchy of PHPUnit_TextUI_ResultPrinter
class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener {
const EVENT_TEST_START = 0;
const EVENT_TEST_END = 1;
const EVENT_TESTSUITE_START = 2;
const EVENT_TESTSUITE_END = 3;
/**
* @var integer
*/
protected $column = 0;
/**
* @var integer
*/
protected $maxColumn;
/**
* @var boolean
*/
protected $lastTestFailed = FALSE;
/**
* @var integer
*/
protected $numAssertions = 0;
/**
* @var integer
*/
protected $numTests = -1;
/**
* @var integer
*/
protected $numTestsRun = 0;
/**
* @var integer
*/
protected $numTestsWidth;
/**
* @var boolean
*/
protected $colors = FALSE;
/**
* @var boolean
*/
protected $debug = FALSE;
/**
* @var boolean
*/
protected $verbose = FALSE;
/**
* Constructor.
*
* @param mixed $out
* @param boolean $verbose
* @param boolean $colors
* @param boolean $debug
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.0.0
*/
public function __construct($out = NULL, $verbose = FALSE, $colors = FALSE, $debug = FALSE) {
parent::__construct($out);
if (is_bool($verbose)) {
$this->verbose = $verbose;
}
else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
}
if (is_bool($colors)) {
$this->colors = $colors;
}
else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
}
if (is_bool($debug)) {
$this->debug = $debug;
}
else {
throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
}
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
public function printResult(PHPUnit_Framework_TestResult $result) {
$this
->printHeader();
if ($result
->errorCount() > 0) {
$this
->printErrors($result);
}
if ($result
->failureCount() > 0) {
if ($result
->errorCount() > 0) {
print "\n--\n\n";
}
$this
->printFailures($result);
}
if ($this->verbose) {
if ($result
->deprecatedFeaturesCount() > 0) {
if ($result
->failureCount() > 0) {
print "\n--\n\nDeprecated PHPUnit features are being used";
}
foreach ($result
->deprecatedFeatures() as $deprecatedFeature) {
$this
->write($deprecatedFeature . "\n\n");
}
}
if ($result
->notImplementedCount() > 0) {
if ($result
->failureCount() > 0) {
print "\n--\n\n";
}
$this
->printIncompletes($result);
}
if ($result
->skippedCount() > 0) {
if ($result
->notImplementedCount() > 0) {
print "\n--\n\n";
}
$this
->printSkipped($result);
}
}
$this
->printFooter($result);
}
/**
* @param array $defects
* @param integer $count
* @param string $type
*/
protected function printDefects(array $defects, $count, $type) {
static $called = FALSE;
if ($count == 0) {
return;
}
$this
->write(sprintf("%sThere %s %d %s%s:\n", $called ? "\n" : '', $count == 1 ? 'was' : 'were', $count, $type, $count == 1 ? '' : 's'));
$i = 1;
foreach ($defects as $defect) {
$this
->printDefect($defect, $i++);
}
$called = TRUE;
}
/**
* @param PHPUnit_Framework_TestFailure $defect
* @param integer $count
*/
protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count) {
$this
->printDefectHeader($defect, $count);
$this
->printDefectTrace($defect);
}
/**
* @param PHPUnit_Framework_TestFailure $defect
* @param integer $count
*/
protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count) {
$failedTest = $defect
->failedTest();
if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
$testName = $failedTest
->toString();
}
else {
$testName = get_class($failedTest);
}
$this
->write(sprintf("\n%d) %s\n", $count, $testName));
}
/**
* @param PHPUnit_Framework_TestFailure $defect
*/
protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect) {
$this
->write($defect
->getExceptionAsString() . "\n" . PHPUnit_Util_Filter::getFilteredStacktrace($defect
->thrownException()));
$e = $defect
->thrownException()
->getPrevious();
while ($e) {
$this
->write("\nCaused by\n" . PHPUnit_Framework_TestFailure::exceptionToString($e) . "\n" . PHPUnit_Util_Filter::getFilteredStacktrace($e));
$e = $e
->getPrevious();
}
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printErrors(PHPUnit_Framework_TestResult $result) {
$this
->printDefects($result
->errors(), $result
->errorCount(), 'error');
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printFailures(PHPUnit_Framework_TestResult $result) {
$this
->printDefects($result
->failures(), $result
->failureCount(), 'failure');
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printIncompletes(PHPUnit_Framework_TestResult $result) {
$this
->printDefects($result
->notImplemented(), $result
->notImplementedCount(), 'incomplete test');
}
/**
* @param PHPUnit_Framework_TestResult $result
* @since Method available since Release 3.0.0
*/
protected function printSkipped(PHPUnit_Framework_TestResult $result) {
$this
->printDefects($result
->skipped(), $result
->skippedCount(), 'skipped test');
}
protected function printHeader() {
$this
->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
}
/**
* @param PHPUnit_Framework_TestResult $result
*/
protected function printFooter(PHPUnit_Framework_TestResult $result) {
if (count($result) === 0) {
if ($this->colors) {
$this
->write("\33[30;43m\33[2K");
}
$this
->write("No tests executed!\n");
if ($this->colors) {
$this
->write("\33[0m\33[2K");
}
}
else {
if ($result
->wasSuccessful() && $result
->allCompletelyImplemented() && $result
->noneSkipped()) {
if ($this->colors) {
$this
->write("\33[30;42m\33[2K");
}
$this
->write(sprintf("OK (%d test%s, %d assertion%s)\n", count($result), count($result) == 1 ? '' : 's', $this->numAssertions, $this->numAssertions == 1 ? '' : 's'));
if ($this->colors) {
$this
->write("\33[0m\33[2K");
}
}
else {
if ((!$result
->allCompletelyImplemented() || !$result
->noneSkipped()) && $result
->wasSuccessful()) {
if ($this->colors) {
$this
->write("\33[30;43m\33[2KOK, but incomplete or skipped tests!\n" . "\33[0m\33[30;43m\33[2K");
}
else {
$this
->write("OK, but incomplete or skipped tests!\n");
}
$this
->write(sprintf("Tests: %d, Assertions: %d%s%s.\n", count($result), $this->numAssertions, $this
->getCountString($result
->notImplementedCount(), 'Incomplete'), $this
->getCountString($result
->skippedCount(), 'Skipped')));
if ($this->colors) {
$this
->write("\33[0m\33[2K");
}
}
else {
$this
->write("\n");
if ($this->colors) {
$this
->write("\33[37;41m\33[2KFAILURES!\n\33[0m\33[37;41m\33[2K");
}
else {
$this
->write("FAILURES!\n");
}
$this
->write(sprintf("Tests: %d, Assertions: %s%s%s%s%s.\n", count($result), $this->numAssertions, $this
->getCountString($result
->failureCount(), 'Failures'), $this
->getCountString($result
->errorCount(), 'Errors'), $this
->getCountString($result
->notImplementedCount(), 'Incomplete'), $this
->getCountString($result
->skippedCount(), 'Skipped')));
if ($this->colors) {
$this
->write("\33[0m\33[2K");
}
}
}
}
if (!$this->verbose && $result
->deprecatedFeaturesCount() > 0) {
$message = sprintf("Warning: Deprecated PHPUnit features are being used %s times!\n" . "Use --verbose for more information.\n", $result
->deprecatedFeaturesCount());
if ($this->colors) {
$message = "\33[37;41m\33[2K" . $message . "\33[0m";
}
$this
->write("\n" . $message);
}
}
/**
* @param integer $count
* @param string $name
* @return string
* @since Method available since Release 3.0.0
*/
protected function getCountString($count, $name) {
$string = '';
if ($count > 0) {
$string = sprintf(', %s: %d', $name, $count);
}
return $string;
}
/**
*/
public function printWaitPrompt() {
$this
->write("\n<RETURN> to continue\n");
}
/**
* An error occurred.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
if ($this->colors) {
$this
->writeProgress("\33[31;1mE\33[0m");
}
else {
$this
->writeProgress('E');
}
$this->lastTestFailed = TRUE;
}
/**
* A failure occurred.
*
* @param PHPUnit_Framework_Test $test
* @param PHPUnit_Framework_AssertionFailedError $e
* @param float $time
*/
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
if ($this->colors) {
$this
->writeProgress("\33[41;37mF\33[0m");
}
else {
$this
->writeProgress('F');
}
$this->lastTestFailed = TRUE;
}
/**
* Incomplete test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
*/
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
if ($this->colors) {
$this
->writeProgress("\33[33;1mI\33[0m");
}
else {
$this
->writeProgress('I');
}
$this->lastTestFailed = TRUE;
}
/**
* Skipped test.
*
* @param PHPUnit_Framework_Test $test
* @param Exception $e
* @param float $time
* @since Method available since Release 3.0.0
*/
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {
if ($this->colors) {
$this
->writeProgress("\33[36;1mS\33[0m");
}
else {
$this
->writeProgress('S');
}
$this->lastTestFailed = TRUE;
}
/**
* A testsuite started.
*
* @param PHPUnit_Framework_TestSuite $suite
* @since Method available since Release 2.2.0
*/
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {
if ($this->numTests == -1) {
$this->numTests = count($suite);
$this->numTestsWidth = strlen((string) $this->numTests);
$this->maxColumn = 69 - 2 * $this->numTestsWidth;
}
}
/**
* A testsuite ended.
*
* @param PHPUnit_Framework_TestSuite $suite
* @since Method available since Release 2.2.0
*/
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
}
/**
* A test started.
*
* @param PHPUnit_Framework_Test $test
*/
public function startTest(PHPUnit_Framework_Test $test) {
if ($this->debug) {
$this
->write(sprintf("\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test)));
}
}
/**
* A test ended.
*
* @param PHPUnit_Framework_Test $test
* @param float $time
*/
public function endTest(PHPUnit_Framework_Test $test, $time) {
if (!$this->lastTestFailed) {
$this
->writeProgress('.');
}
if ($test instanceof PHPUnit_Framework_TestCase) {
$this->numAssertions += $test
->getNumAssertions();
}
else {
if ($test instanceof PHPUnit_Extensions_PhptTestCase) {
$this->numAssertions++;
}
}
$this->lastTestFailed = FALSE;
if ($test instanceof PHPUnit_Framework_TestCase) {
if (!$test
->hasPerformedExpectationsOnOutput()) {
$this
->write($test
->getActualOutput());
}
}
}
/**
* @param string $progress
*/
protected function writeProgress($progress) {
$this
->write($progress);
$this->column++;
$this->numTestsRun++;
if ($this->column == $this->maxColumn) {
$this
->write(sprintf(' %' . $this->numTestsWidth . 'd / %' . $this->numTestsWidth . 'd (%3s%%)', $this->numTestsRun, $this->numTests, floor($this->numTestsRun / $this->numTests * 100)));
$this
->writeNewLine();
}
}
protected function writeNewLine() {
$this->column = 0;
$this
->write("\n");
}
}