From 172041c6d0ca7ac5587d2cdadedeeb494e0cfd33 Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Thu, 14 Dec 2017 23:04:33 +0100 Subject: [PATCH 1/6] Replace CLI testdox printer with rpkamp/fancy-testdox-printer --- .travis.yml | 2 +- phpunit.xml | 1 + src/TextUI/Command.php | 3 +- src/TextUI/TestDox/TestResult.php | 149 +++++++++++++ src/TextUI/TestDoxPrinter.php | 205 ++++++++++++++++++ src/Util/TestDox/TextResultPrinter.php | 3 +- tests/TextUI/dataprovider-testdox.phpt | 13 +- .../defaulttestsuite-using-testsuite.phpt | 7 +- tests/TextUI/defaulttestsuite.phpt | 7 +- tests/TextUI/testdox.phpt | 8 +- 10 files changed, 386 insertions(+), 12 deletions(-) create mode 100644 src/TextUI/TestDox/TestResult.php create mode 100644 src/TextUI/TestDoxPrinter.php diff --git a/.travis.yml b/.travis.yml index 9825e4cc700..85a651135de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ before_script: - echo 'assert.exception=On' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini script: - - ./phpunit --coverage-clover=coverage.xml + - ./phpunit --coverage-clover=coverage.xml --testdox --color=auto - ./phpunit --configuration ./build/travis-ci-fail.xml > /dev/null; if [ $? -eq 0 ]; then echo "SHOULD FAIL"; false; else echo "fail checked"; fi; - xmllint --noout --schema phpunit.xsd phpunit.xml - xmllint --noout --schema phpunit.xsd tests/_files/configuration.xml diff --git a/phpunit.xml b/phpunit.xml index 03ad7b994eb..b9cd23b2153 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,6 +8,7 @@ tests/Framework tests/Runner tests/Util + tests/TextUI diff --git a/src/TextUI/Command.php b/src/TextUI/Command.php index 0ba1e0fc393..0dc8457f239 100644 --- a/src/TextUI/Command.php +++ b/src/TextUI/Command.php @@ -30,7 +30,6 @@ use PHPUnit\Util\Getopt; use PHPUnit\Util\Log\TeamCity; use PHPUnit\Util\Printer; -use PHPUnit\Util\TestDox\TextResultPrinter; use PHPUnit\Util\TextTestListRenderer; use PHPUnit\Util\XmlTestListRenderer; use ReflectionClass; @@ -548,7 +547,7 @@ protected function handleArguments(array $argv): void break; case '--testdox': - $this->arguments['printer'] = TextResultPrinter::class; + $this->arguments['printer'] = TestDoxPrinter::class; break; diff --git a/src/TextUI/TestDox/TestResult.php b/src/TextUI/TestDox/TestResult.php new file mode 100644 index 00000000000..66291ee6527 --- /dev/null +++ b/src/TextUI/TestDox/TestResult.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI\TestDox; + +final class TestResult +{ + /** + * @var callable + */ + private $colorize; + + /** + * @var string + */ + private $testClass; + + /** + * @var string + */ + private $testMethod; + + /** + * @var bool + */ + private $testSuccesful; + + /** + * @var string + */ + private $symbol; + + /** + * @var string + */ + private $additionalInformation; + + /** + * @var bool + */ + private $additionalInformationVerbose; + + /** + * @var float + */ + private $runtime; + + public function __construct( + callable $colorize, + string $testClass, + string $testMethod + ) { + $this->colorize = $colorize; + $this->testClass = $testClass; + $this->testMethod = $testMethod; + $this->testSuccesful = true; + $this->symbol = ($this->colorize)('fg-green', '✔'); + $this->additionalInformation = ''; + } + + public function isTestSuccessful() + { + return $this->testSuccesful; + } + + public function fail( + string $symbol, + string $additionalInformation, + bool $additionalInformationVerbose = false + ): void { + $this->testSuccesful = false; + $this->symbol = $symbol; + $this->additionalInformation = $additionalInformation; + $this->additionalInformationVerbose = $additionalInformationVerbose; + } + + public function setRuntime(float $runtime): void + { + $this->runtime = $runtime; + } + + public function toString(?self $previousTestResult, $verbose = false): string + { + return \sprintf( + "%s %s %s %s\n%s", + $this->getClassNameHeader($previousTestResult ? $previousTestResult->testClass : null), + $this->symbol, + $this->testMethod, + $this->getFormattedRuntime(), + $this->getFormattedAdditionalInformation($verbose) + ); + } + + private function getClassNameHeader(?string $previousTestClass): string + { + $className = ''; + if ($this->testClass !== $previousTestClass) { + if (null !== $previousTestClass) { + $className = "\n"; + } + $className .= \sprintf("%s\n", $this->testClass); + } + + return $className; + } + + private function getFormattedRuntime(): string + { + if ($this->runtime > 5) { + return ($this->colorize)('fg-red', \sprintf('[%.2f ms]', $this->runtime * 1000)); + } + + if ($this->runtime > 1) { + return ($this->colorize)('fg-yellow', \sprintf('[%.2f ms]', $this->runtime * 1000)); + } + + return \sprintf('[%.2f ms]', $this->runtime * 1000); + } + + private function getFormattedAdditionalInformation($verbose): string + { + if ($this->additionalInformation === '') { + return ''; + } + + if ($this->additionalInformationVerbose && !$verbose) { + return ''; + } + + return \sprintf( + " │\n%s\n\n", + \implode( + "\n", + \array_map( + function (string $text) { + return \sprintf(' │ %s', $text); + }, + \explode("\n", $this->additionalInformation) + ) + ) + ); + } +} diff --git a/src/TextUI/TestDoxPrinter.php b/src/TextUI/TestDoxPrinter.php new file mode 100644 index 00000000000..cf99c18b6a0 --- /dev/null +++ b/src/TextUI/TestDoxPrinter.php @@ -0,0 +1,205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestResult; +use PHPUnit\Framework\Warning; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\TextUI\TestDox\TestResult as TestDoxTestResult; +use PHPUnit\Util\TestDox\NamePrettifier; + +/** + * This printer is for CLI output only. For the classes that output to file, html and xml, + * please refer to the PHPUnit\Util\TestDox namespace + */ +class TestDoxPrinter extends ResultPrinter +{ + /** + * @var TestDoxTestResult + */ + private $currentTestResult; + + /** + * @var TestDoxTestResult + */ + private $previousTestResult; + + /** + * @var TestDoxTestResult[] + */ + private $nonSuccessfulTestResults = []; + + /** + * @var NamePrettifier + */ + private $prettifier; + + public function __construct( + $out = null, + $verbose = false, + $colors = self::COLOR_DEFAULT, + $debug = false, + $numberOfColumns = 80, + $reverse = false + ) { + parent::__construct($out, $verbose, $colors, $debug, $numberOfColumns, $reverse); + + $this->prettifier = new NamePrettifier(); + } + + public function startTest(Test $test): void + { + if (!$test instanceof TestCase && !$test instanceof PhptTestCase) { + return; + } + + $class = \get_class($test); + if ($test instanceof TestCase) { + $annotations = $test->getAnnotations(); + + if (isset($annotations['class']['testdox'][0])) { + $className = $annotations['class']['testdox'][0]; + } else { + $className = $this->prettifier->prettifyTestClass($class); + } + + if (isset($annotations['method']['testdox'][0])) { + $testMethod = $annotations['method']['testdox'][0]; + } else { + $testMethod = $this->prettifier->prettifyTestMethod($test->getName(false)); + } + $testMethod .= substr($test->getDataSetAsString(false), 5); + } elseif ($test instanceof PhptTestCase) { + $className = $class; + $testMethod = $test->getName(); + } + + $this->currentTestResult = new TestDoxTestResult( + function (string $color, string $buffer) { + return $this->formatWithColor($color, $buffer); + }, + $className, + $testMethod + ); + + parent::startTest($test); + } + + public function endTest(Test $test, $time): void + { + if (!$test instanceof TestCase && !$test instanceof PhptTestCase) { + return; + } + + parent::endTest($test, $time); + + $this->currentTestResult->setRuntime($time); + + $this->write($this->currentTestResult->toString($this->previousTestResult, $this->verbose)); + + $this->previousTestResult = $this->currentTestResult; + + if (!$this->currentTestResult->isTestSuccessful()) { + $this->nonSuccessfulTestResults[] = $this->currentTestResult; + } + } + + public function addError(Test $test, \Throwable $t, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-yellow', '✘'), + (string) $t + ); + } + + public function addWarning(Test $test, Warning $e, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-yellow', '✘'), + (string) $e + ); + } + + public function addFailure(Test $test, AssertionFailedError $e, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-red', '✘'), + (string) $e + ); + } + + public function addIncompleteTest(Test $test, \Throwable $t, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-yellow', '∅'), + (string) $t, + true + ); + } + + public function addRiskyTest(Test $test, \Throwable $t, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-yellow', '☢'), + (string) $t, + true + ); + } + + public function addSkippedTest(Test $test, \Throwable $e, $time): void + { + $this->currentTestResult->fail( + $this->formatWithColor('fg-yellow', '→'), + (string) $e, + true + ); + } + + public function writeProgress($progress): void + { + // NOOP, block normal behavior of \PHPUnit\TextUI\ResultPrinter + } + + public function flush(): void + { + } + + public function printResult(TestResult $result): void + { + $this->printHeader(); + + $this->printNonSuccessfulTestsSummary($result->count()); + + $this->printFooter($result); + } + + public function printNonSuccessfulTestsSummary(int $numberOfExecutedTests): void + { + $numberOfNonSuccessfulTests = \count($this->nonSuccessfulTestResults); + if ($numberOfNonSuccessfulTests === 0) { + return; + } + + if (($numberOfNonSuccessfulTests / $numberOfExecutedTests) >= 0.7) { + return; + } + + $this->write("Summary of non-successful tests:\n\n"); + + $previousTestResult = null; + foreach ($this->nonSuccessfulTestResults as $testResult) { + $this->write($testResult->toString($previousTestResult, $this->verbose)); + $previousTestResult = $testResult; + } + } +} diff --git a/src/Util/TestDox/TextResultPrinter.php b/src/Util/TestDox/TextResultPrinter.php index 68153947c92..189491df953 100644 --- a/src/Util/TestDox/TextResultPrinter.php +++ b/src/Util/TestDox/TextResultPrinter.php @@ -10,7 +10,8 @@ namespace PHPUnit\Util\TestDox; /** - * Prints TestDox documentation in text format. + * Prints TestDox documentation in text format to files. + * For the CLI testdox printer please refer to \PHPUnit\TextUI\TextDoxPrinter. */ class TextResultPrinter extends ResultPrinter { diff --git a/tests/TextUI/dataprovider-testdox.phpt b/tests/TextUI/dataprovider-testdox.phpt index eb7c2315692..a09b08274b1 100644 --- a/tests/TextUI/dataprovider-testdox.phpt +++ b/tests/TextUI/dataprovider-testdox.phpt @@ -13,7 +13,12 @@ PHPUnit\TextUI\Command::main(); PHPUnit %s by Sebastian Bergmann and contributors. DataProviderTestDox - [x] Does something with one - [x] Does something with two - [x] Does something else with one - [x] Does something else with two + ✔ Does something with data set "one" [%f ms] + ✔ Does something with data set "two" [%f ms] + ✔ Does something else with data set "one" [%f ms] + ✔ Does something else with data set "two" [%f ms] + + +Time: %d ms, Memory: %fMB + +OK (4 tests, 4 assertions) diff --git a/tests/TextUI/defaulttestsuite-using-testsuite.phpt b/tests/TextUI/defaulttestsuite-using-testsuite.phpt index 7985193d554..e3aebf85beb 100644 --- a/tests/TextUI/defaulttestsuite-using-testsuite.phpt +++ b/tests/TextUI/defaulttestsuite-using-testsuite.phpt @@ -14,4 +14,9 @@ PHPUnit\TextUI\Command::main(); PHPUnit %s by Sebastian Bergmann and contributors. DummyFoo - [x] Foo equals foo + ✔ Foo equals foo [%f ms] + + +Time: %d ms, Memory: %fMB + +OK (1 test, 1 assertion) diff --git a/tests/TextUI/defaulttestsuite.phpt b/tests/TextUI/defaulttestsuite.phpt index 1a97c9f942d..bf0be2adada 100644 --- a/tests/TextUI/defaulttestsuite.phpt +++ b/tests/TextUI/defaulttestsuite.phpt @@ -12,4 +12,9 @@ PHPUnit\TextUI\Command::main(); PHPUnit %s by Sebastian Bergmann and contributors. DummyBar - [x] Bar equals bar + ✔ Bar equals bar [%f ms] + + +Time: %d ms, Memory: %fMB + +OK (1 test, 1 assertion) diff --git a/tests/TextUI/testdox.phpt b/tests/TextUI/testdox.phpt index 6addd3316a5..3fb810985d5 100644 --- a/tests/TextUI/testdox.phpt +++ b/tests/TextUI/testdox.phpt @@ -13,6 +13,10 @@ PHPUnit\TextUI\Command::main(); PHPUnit %s by Sebastian Bergmann and contributors. BankAccount - [x] Balance is initially zero - [x] Balance cannot become negative + ✔ Balance is initially zero [%f ms] + ✔ Balance cannot become negative [%f ms] + +Time: %d ms, Memory: %fMB + +OK (3 tests, 3 assertions) From e843b3db6de3926fb88ce9d2ba748a60ff4e7fcf Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Fri, 15 Dec 2017 07:57:31 +0100 Subject: [PATCH 2/6] Revert changes to .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 85a651135de..9825e4cc700 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ before_script: - echo 'assert.exception=On' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini script: - - ./phpunit --coverage-clover=coverage.xml --testdox --color=auto + - ./phpunit --coverage-clover=coverage.xml - ./phpunit --configuration ./build/travis-ci-fail.xml > /dev/null; if [ $? -eq 0 ]; then echo "SHOULD FAIL"; false; else echo "fail checked"; fi; - xmllint --noout --schema phpunit.xsd phpunit.xml - xmllint --noout --schema phpunit.xsd tests/_files/configuration.xml From 8d724915f4b2fee86dec17bd7fbeb800c7437136 Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Fri, 15 Dec 2017 08:20:05 +0100 Subject: [PATCH 3/6] Rename new testdox printer to PHPUnit\Util\TestDox\CliTestDoxPrinter --- phpunit.xml | 1 - src/TextUI/Command.php | 3 +- .../TestDox/CliTestDoxPrinter.php} | 8 +- src/{TextUI => Util}/TestDox/TestResult.php | 2 +- tests/Util/TestDox/CliTestDoxPrinterTest.php | 263 ++++++++++++++++++ .../TestDox/TestableCliTestDoxPrinter.php | 25 ++ 6 files changed, 295 insertions(+), 7 deletions(-) rename src/{TextUI/TestDoxPrinter.php => Util/TestDox/CliTestDoxPrinter.php} (97%) rename src/{TextUI => Util}/TestDox/TestResult.php (99%) create mode 100644 tests/Util/TestDox/CliTestDoxPrinterTest.php create mode 100644 tests/Util/TestDox/TestableCliTestDoxPrinter.php diff --git a/phpunit.xml b/phpunit.xml index b9cd23b2153..03ad7b994eb 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,7 +8,6 @@ tests/Framework tests/Runner tests/Util - tests/TextUI diff --git a/src/TextUI/Command.php b/src/TextUI/Command.php index 0dc8457f239..1eff22c25d1 100644 --- a/src/TextUI/Command.php +++ b/src/TextUI/Command.php @@ -30,6 +30,7 @@ use PHPUnit\Util\Getopt; use PHPUnit\Util\Log\TeamCity; use PHPUnit\Util\Printer; +use PHPUnit\Util\TestDox\CliTestDoxPrinter; use PHPUnit\Util\TextTestListRenderer; use PHPUnit\Util\XmlTestListRenderer; use ReflectionClass; @@ -547,7 +548,7 @@ protected function handleArguments(array $argv): void break; case '--testdox': - $this->arguments['printer'] = TestDoxPrinter::class; + $this->arguments['printer'] = CliTestDoxPrinter::class; break; diff --git a/src/TextUI/TestDoxPrinter.php b/src/Util/TestDox/CliTestDoxPrinter.php similarity index 97% rename from src/TextUI/TestDoxPrinter.php rename to src/Util/TestDox/CliTestDoxPrinter.php index cf99c18b6a0..e75d8fd2238 100644 --- a/src/TextUI/TestDoxPrinter.php +++ b/src/Util/TestDox/CliTestDoxPrinter.php @@ -7,7 +7,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\TextUI; +namespace PHPUnit\Util\TestDox; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\Test; @@ -15,14 +15,14 @@ use PHPUnit\Framework\TestResult; use PHPUnit\Framework\Warning; use PHPUnit\Runner\PhptTestCase; -use PHPUnit\TextUI\TestDox\TestResult as TestDoxTestResult; -use PHPUnit\Util\TestDox\NamePrettifier; +use PHPUnit\TextUI\ResultPrinter; +use PHPUnit\Util\TestDox\TestResult as TestDoxTestResult; /** * This printer is for CLI output only. For the classes that output to file, html and xml, * please refer to the PHPUnit\Util\TestDox namespace */ -class TestDoxPrinter extends ResultPrinter +class CliTestDoxPrinter extends ResultPrinter { /** * @var TestDoxTestResult diff --git a/src/TextUI/TestDox/TestResult.php b/src/Util/TestDox/TestResult.php similarity index 99% rename from src/TextUI/TestDox/TestResult.php rename to src/Util/TestDox/TestResult.php index 66291ee6527..77873c8e3d8 100644 --- a/src/TextUI/TestDox/TestResult.php +++ b/src/Util/TestDox/TestResult.php @@ -7,7 +7,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace PHPUnit\TextUI\TestDox; +namespace PHPUnit\Util\TestDox; final class TestResult { diff --git a/tests/Util/TestDox/CliTestDoxPrinterTest.php b/tests/Util/TestDox/CliTestDoxPrinterTest.php new file mode 100644 index 00000000000..a60919635d5 --- /dev/null +++ b/tests/Util/TestDox/CliTestDoxPrinterTest.php @@ -0,0 +1,263 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\TestDox; + +use Exception; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Warning; + +final class CliTestDoxPrinterTest extends TestCase +{ + /** + * @test + */ + public function it_should_print_the_class_name_of_test_class() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->endTest($this, 0); + + $this->assertStringStartsWith('PHPUnit\Util\TestDox\CliTestDoxPrinter', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_testdox_version_of_test_method() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->endTest($this, 0.001); + + $this->assertContains('It should print testdox version of test method', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_check_mark_on_passed_test() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->endTest($this, 0.001); + + $this->assertContains('✔', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_not_print_additional_information_on_test_passed() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->endTest($this, 0.001); + + $this->assertNotContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_cross_on_test_with_error() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addError($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('✘', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_test_with_error() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addError($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_cross_on_test_with_warning() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addWarning($this, new Warning(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('✘', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_test_with_warning() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addWarning($this, new Warning(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_cross_on_test_with_failure() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addFailure($this, new AssertionFailedError(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('✘', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_test_with_failure() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addFailure($this, new AssertionFailedError(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_empty_set_symbol_on_incomplete_test() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addIncompleteTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('∅', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_not_print_additional_information_on_incomplete_test_when_not_verbose() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addIncompleteTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertNotContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_incomplete_test_when_verbose() + { + $printer = new TestableCliTestDoxPrinter(null, true); + $printer->startTest($this); + $printer->addIncompleteTest($this, new Exception('E_X_C_E_P_T_I_O_N'), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + $this->assertContains('E_X_C_E_P_T_I_O_N', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_radioactive_symbol_on_test_risky() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addRiskyTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('☢', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_not_print_additional_information_on_risky_test_when_not_verbose() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addRiskyTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertNotContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_risky_test_when_verbose() + { + $printer = new TestableCliTestDoxPrinter(null, true); + $printer->startTest($this); + $printer->addRiskyTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_arrow_on_skipped_test() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addSkippedTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('→', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_not_print_additional_information_on_skipped_test_when_not_verbose() + { + $printer = new TestableCliTestDoxPrinter(); + $printer->startTest($this); + $printer->addSkippedTest($this, new Exception(), 0); + $printer->endTest($this, 0.001); + + $this->assertNotContains('│', $printer->getBuffer()); + } + + /** + * @test + */ + public function it_should_print_additional_information_on_skipped_test_when_verbose() + { + $printer = new TestableCliTestDoxPrinter(null, true); + $printer->startTest($this); + $printer->addSkippedTest($this, new Exception('S_K_I_P_P_E_D'), 0); + $printer->endTest($this, 0.001); + + $this->assertContains('│', $printer->getBuffer()); + $this->assertContains('S_K_I_P_P_E_D', $printer->getBuffer()); + } +} diff --git a/tests/Util/TestDox/TestableCliTestDoxPrinter.php b/tests/Util/TestDox/TestableCliTestDoxPrinter.php new file mode 100644 index 00000000000..e93d27d4bcb --- /dev/null +++ b/tests/Util/TestDox/TestableCliTestDoxPrinter.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\TestDox; + +class TestableCliTestDoxPrinter extends CliTestDoxPrinter +{ + private $buffer; + + public function write($text): void + { + $this->buffer .= $text; + } + + public function getBuffer(): string + { + return $this->buffer; + } +} From 8e5175879a72c517cd1c68d366d07123f67112af Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Fri, 15 Dec 2017 08:33:50 +0100 Subject: [PATCH 4/6] Accept that new testdox printer does not suppress duplicate test methods --- tests/TextUI/testdox.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/TextUI/testdox.phpt b/tests/TextUI/testdox.phpt index 3fb810985d5..6918f458e7f 100644 --- a/tests/TextUI/testdox.phpt +++ b/tests/TextUI/testdox.phpt @@ -15,6 +15,7 @@ PHPUnit %s by Sebastian Bergmann and contributors. BankAccount ✔ Balance is initially zero [%f ms] ✔ Balance cannot become negative [%f ms] + ✔ Balance cannot become negative [%f ms] Time: %d ms, Memory: %fMB From 2b8f9ed2a81f91d5ca513c5f9ece0ce5c0178f80 Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Fri, 15 Dec 2017 09:02:36 +0100 Subject: [PATCH 5/6] No longer suppress repeating test method names in testdox output --- src/Util/TestDox/ResultPrinter.php | 20 +++----------------- tests/TextUI/testdox-html.phpt | 1 + tests/TextUI/testdox-text.phpt | 1 + 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Util/TestDox/ResultPrinter.php b/src/Util/TestDox/ResultPrinter.php index 3c9a45df89d..34ea374599b 100644 --- a/src/Util/TestDox/ResultPrinter.php +++ b/src/Util/TestDox/ResultPrinter.php @@ -304,21 +304,7 @@ public function endTest(Test $test, $time): void return; } - if (!isset($this->tests[$this->currentTestMethodPrettified])) { - if ($this->testStatus === BaseTestRunner::STATUS_PASSED) { - $this->tests[$this->currentTestMethodPrettified]['success'] = 1; - $this->tests[$this->currentTestMethodPrettified]['failure'] = 0; - } else { - $this->tests[$this->currentTestMethodPrettified]['success'] = 0; - $this->tests[$this->currentTestMethodPrettified]['failure'] = 1; - } - } else { - if ($this->testStatus === BaseTestRunner::STATUS_PASSED) { - $this->tests[$this->currentTestMethodPrettified]['success']++; - } else { - $this->tests[$this->currentTestMethodPrettified]['failure']++; - } - } + $this->tests[] = [$this->currentTestMethodPrettified, $this->testStatus]; $this->currentTestClassPrettified = null; $this->currentTestMethodPrettified = null; @@ -326,8 +312,8 @@ public function endTest(Test $test, $time): void protected function doEndClass(): void { - foreach ($this->tests as $name => $data) { - $this->onTest($name, $data['failure'] === 0); + foreach ($this->tests as $test) { + $this->onTest($test[0], $test[1] === BaseTestRunner::STATUS_PASSED); } $this->endClass($this->testClass); diff --git a/tests/TextUI/testdox-html.phpt b/tests/TextUI/testdox-html.phpt index b2dd9a208f4..8453712118b 100644 --- a/tests/TextUI/testdox-html.phpt +++ b/tests/TextUI/testdox-html.phpt @@ -47,6 +47,7 @@ PHPUnit %s by Sebastian Bergmann and contributors.
    ... 3 / 3 (100%)
  • ✓ Balance is initially zero
  • ✓ Balance cannot become negative
  • +
  • ✓ Balance cannot become negative
diff --git a/tests/TextUI/testdox-text.phpt b/tests/TextUI/testdox-text.phpt index 090d1da8b9b..f6bda8d1daf 100644 --- a/tests/TextUI/testdox-text.phpt +++ b/tests/TextUI/testdox-text.phpt @@ -16,6 +16,7 @@ PHPUnit %s by Sebastian Bergmann and contributors. BankAccount ... 3 / 3 (100%) [x] Balance is initially zero [x] Balance cannot become negative + [x] Balance cannot become negative From cd956f789c53f22f1b382d15f14fc62f678f225a Mon Sep 17 00:00:00 2001 From: Remon van de Kamp Date: Fri, 15 Dec 2017 09:19:13 +0100 Subject: [PATCH 6/6] Prevent two consecutive blank lines in testdox output --- src/Util/TestDox/CliTestDoxPrinter.php | 6 +++++ src/Util/TestDox/TestResult.php | 24 +++++++++++++------ tests/TextUI/dataprovider-testdox.phpt | 1 - .../defaulttestsuite-using-testsuite.phpt | 1 - tests/TextUI/defaulttestsuite.phpt | 1 - tests/TextUI/testdox.phpt | 1 - 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/Util/TestDox/CliTestDoxPrinter.php b/src/Util/TestDox/CliTestDoxPrinter.php index e75d8fd2238..46dc797ec19 100644 --- a/src/Util/TestDox/CliTestDoxPrinter.php +++ b/src/Util/TestDox/CliTestDoxPrinter.php @@ -9,6 +9,7 @@ */ namespace PHPUnit\Util\TestDox; +use PHP_Timer; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\Test; use PHPUnit\Framework\TestCase; @@ -183,6 +184,11 @@ public function printResult(TestResult $result): void $this->printFooter($result); } + protected function printHeader(): void + { + $this->write("\n" . PHP_Timer::resourceUsage() . "\n\n"); + } + public function printNonSuccessfulTestsSummary(int $numberOfExecutedTests): void { $numberOfNonSuccessfulTests = \count($this->nonSuccessfulTestResults); diff --git a/src/Util/TestDox/TestResult.php b/src/Util/TestDox/TestResult.php index 77873c8e3d8..bfbc2d18d9b 100644 --- a/src/Util/TestDox/TestResult.php +++ b/src/Util/TestDox/TestResult.php @@ -88,7 +88,8 @@ public function setRuntime(float $runtime): void public function toString(?self $previousTestResult, $verbose = false): string { return \sprintf( - "%s %s %s %s\n%s", + "%s%s %s %s %s\n%s", + $previousTestResult && $previousTestResult->additionInformationPrintable($verbose) ? "\n" : '', $this->getClassNameHeader($previousTestResult ? $previousTestResult->testClass : null), $this->symbol, $this->testMethod, @@ -125,16 +126,12 @@ private function getFormattedRuntime(): string private function getFormattedAdditionalInformation($verbose): string { - if ($this->additionalInformation === '') { - return ''; - } - - if ($this->additionalInformationVerbose && !$verbose) { + if (!$this->additionInformationPrintable($verbose)) { return ''; } return \sprintf( - " │\n%s\n\n", + " │\n%s\n", \implode( "\n", \array_map( @@ -146,4 +143,17 @@ function (string $text) { ) ); } + + protected function additionInformationPrintable(bool $verbose): bool + { + if ($this->additionalInformation === '') { + return false; + } + + if ($this->additionalInformationVerbose && !$verbose) { + return false; + } + + return true; + } } diff --git a/tests/TextUI/dataprovider-testdox.phpt b/tests/TextUI/dataprovider-testdox.phpt index a09b08274b1..577082a7a91 100644 --- a/tests/TextUI/dataprovider-testdox.phpt +++ b/tests/TextUI/dataprovider-testdox.phpt @@ -18,7 +18,6 @@ DataProviderTestDox ✔ Does something else with data set "one" [%f ms] ✔ Does something else with data set "two" [%f ms] - Time: %d ms, Memory: %fMB OK (4 tests, 4 assertions) diff --git a/tests/TextUI/defaulttestsuite-using-testsuite.phpt b/tests/TextUI/defaulttestsuite-using-testsuite.phpt index e3aebf85beb..036f3653d4b 100644 --- a/tests/TextUI/defaulttestsuite-using-testsuite.phpt +++ b/tests/TextUI/defaulttestsuite-using-testsuite.phpt @@ -16,7 +16,6 @@ PHPUnit %s by Sebastian Bergmann and contributors. DummyFoo ✔ Foo equals foo [%f ms] - Time: %d ms, Memory: %fMB OK (1 test, 1 assertion) diff --git a/tests/TextUI/defaulttestsuite.phpt b/tests/TextUI/defaulttestsuite.phpt index bf0be2adada..2753f71ac67 100644 --- a/tests/TextUI/defaulttestsuite.phpt +++ b/tests/TextUI/defaulttestsuite.phpt @@ -14,7 +14,6 @@ PHPUnit %s by Sebastian Bergmann and contributors. DummyBar ✔ Bar equals bar [%f ms] - Time: %d ms, Memory: %fMB OK (1 test, 1 assertion) diff --git a/tests/TextUI/testdox.phpt b/tests/TextUI/testdox.phpt index 6918f458e7f..65f3a1d1ebc 100644 --- a/tests/TextUI/testdox.phpt +++ b/tests/TextUI/testdox.phpt @@ -17,7 +17,6 @@ BankAccount ✔ Balance cannot become negative [%f ms] ✔ Balance cannot become negative [%f ms] - Time: %d ms, Memory: %fMB OK (3 tests, 3 assertions)