Report logs for each individual test failure
authorErik Bernhardson <ebernhardson@wikimedia.org>
Mon, 4 Mar 2019 21:44:39 +0000 (13:44 -0800)
committerErik Bernhardson <ebernhardson@wikimedia.org>
Wed, 6 Mar 2019 23:13:53 +0000 (15:13 -0800)
The initial implementation of reporting logs with test failures was
incorrect, it always reported the logs of the most recent test run.
Attach logs to the Test when a failure is reported and pull them
back out in the result printer.

Bug: T217489
Change-Id: I5aa55d6fa7a7ec03a2e71636b6b0366ea40605cb

tests/phpunit/MediaWikiLoggerPHPUnitTestListener.php
tests/phpunit/MediaWikiPHPUnitCommand.php
tests/phpunit/MediaWikiPHPUnitResultPrinter.php

index adb0196..f87afb0 100644 (file)
@@ -14,8 +14,6 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
        private $originalSpi;
        /** @var Spi|null */
        private $spi;
-       /** @var array|null */
-       private $lastTestLogs;
 
        /**
         * A test started.
@@ -29,6 +27,40 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
                LoggerFactory::registerProvider( $this->spi );
        }
 
+       public function addRiskyTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addWarning( PHPUnit_Framework_Test $test, PHPUnit\Framework\Warning $e, $time ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       public function addFailure( PHPUnit_Framework_Test $test,
+               PHPUnit_Framework_AssertionFailedError $e, $time
+       ) {
+               $this->augmentTestWithLogs( $test );
+       }
+
+       private function augmentTestWithLogs( PHPUnit_Framework_Test $test ) {
+               if ( $this->spi ) {
+                       $logs = $this->spi->getLogs();
+                       $formatted = $this->formatLogs( $logs );
+                       $test->_formattedMediaWikiLogs = $formatted;
+               }
+       }
+
        /**
         * A test ended.
         *
@@ -36,7 +68,6 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
         * @param float $time
         */
        public function endTest( PHPUnit_Framework_Test $test, $time ) {
-               $this->lastTestLogs = $this->spi->getLogs();
                LoggerFactory::registerProvider( $this->originalSpi );
                $this->originalSpi = null;
                $this->spi = null;
@@ -46,13 +77,10 @@ class MediaWikiLoggerPHPUnitTestListener extends PHPUnit_Framework_BaseTestListe
         * Get string formatted logs generated during the last
         * test to execute.
         *
+        * @param array $logs
         * @return string
         */
-       public function getLog() {
-               $logs = $this->lastTestLogs;
-               if ( !$logs ) {
-                       return '';
-               }
+       private function formatLogs( array $logs ) {
                $message = [];
                foreach ( $logs as $log ) {
                        $message[] = sprintf(
index 5d139ff..6b1d817 100644 (file)
@@ -2,7 +2,6 @@
 
 class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
        private $cliArgs;
-       private $logListener;
 
        public function __construct( $ignorableOptions, $cliArgs ) {
                $ignore = function ( $arg ) {
@@ -21,22 +20,19 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
 
                // Add our own listeners
                $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener;
-               $this->logListener = new MediaWikiLoggerPHPUnitTestListener;
-               $this->arguments['listeners'][] = $this->logListener;
+               $this->arguments['listeners'][] = new MediaWikiLoggerPHPUnitTestListener;
 
                // Output only to stderr to avoid "Headers already sent" problems
                $this->arguments['stderr'] = true;
 
-               // We could create a printer instance and avoid passing the
-               // listener statically, but then we have to recreate the
-               // appropriate arguments handling + defaults.
+               // Use a custom result printer that includes per-test logging output
+               // when nothing is provided.
                if ( !isset( $this->arguments['printer'] ) ) {
                        $this->arguments['printer'] = MediaWikiPHPUnitResultPrinter::class;
                }
        }
 
        protected function createRunner() {
-               MediaWikiPHPUnitResultPrinter::setLogListener( $this->logListener );
                $runner = new MediaWikiTestRunner;
                $runner->setMwCliArgs( $this->cliArgs );
                return $runner;
index e796752..d0ac8ff 100644 (file)
@@ -1,17 +1,13 @@
 <?php
 
 class MediaWikiPHPUnitResultPrinter extends PHPUnit_TextUI_ResultPrinter {
-       /** @var MediaWikiLoggerPHPUnitTestListener */
-       private static $logListener;
-
-       public static function setLogListener( MediaWikiLoggerPHPUnitTestListener $logListener ) {
-               self::$logListener = $logListener;
-       }
-
        protected function printDefectTrace( PHPUnit_Framework_TestFailure $defect ) {
-               $log = self::$logListener->getLog();
-               if ( $log ) {
-                       $this->write( "=== Logs generated by test case\n{$log}\n===\n" );
+               $test = $defect->failedTest();
+               if ( $test !== null && isset( $test->_formattedMediaWikiLogs ) ) {
+                       $log = $test->_formattedMediaWikiLogs;
+                       if ( $log ) {
+                               $this->write( "=== Logs generated by test case\n{$log}\n===\n" );
+                       }
                }
                parent::printDefectTrace( $defect );
        }