Allow debugging of unit tests via wfDebugLog.
authordaniel <daniel.kinzler@wikimedia.de>
Wed, 17 Jul 2013 19:23:28 +0000 (21:23 +0200)
committerDaniel Kinzler <daniel.kinzler@wikimedia.de>
Thu, 25 Jul 2013 09:54:14 +0000 (09:54 +0000)
This adds a listener to the PHPUnit test runner that will report
testing progress via wfDebugLog. This is useful for debugging
situations in which phpunit itself fails to report errors and
does not terminate normally. Having a debug log should at least
help with locating the trigger of the problem.

Change-Id: I433537a7f26197d8cff6f133e26ae5709871500f

tests/TestsAutoLoader.php
tests/phpunit/MediaWikiPHPUnitCommand.php
tests/phpunit/MediaWikiPHPUnitTestListener.php [new file with mode: 0644]

index d7237f7..0939ebe 100644 (file)
@@ -38,6 +38,7 @@ $wgAutoloadClasses += array(
        # tests/phpunit
        'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php",
        'MediaWikiPHPUnitCommand' => "$testDir/phpunit/MediaWikiPHPUnitCommand.php",
+       'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php",
        'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php",
        'MediaWikiProvide' => "$testDir/phpunit/includes/Providers.php",
        'TestUser' => "$testDir/phpunit/includes/TestUser.php",
index f5760ea..387107b 100644 (file)
@@ -12,6 +12,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
                'use-normal-tables' => false,
                'reuse-db' => false,
                'wiki=' => false,
+               'debug-tests' => false,
        );
 
        public function __construct() {
@@ -20,6 +21,22 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command {
                }
        }
 
+       protected function handleArguments(array $argv) {
+               parent::handleArguments( $argv );
+
+               if ( !isset( $this->arguments['listeners'] ) ) {
+                       $this->arguments['listeners'] = array();
+               }
+
+               foreach ($this->options[0] as $option) {
+                       switch ($option[0]) {
+                               case '--debug-tests':
+                                       $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener( 'PHPUnitCommand' );
+                                       break;
+                       }
+               }
+       }
+
        public static function main( $exit = true ) {
                $command = new self;
 
@@ -94,6 +111,9 @@ Database options:
   --reuse-db               Init DB only if tables are missing and keep after finish.
 
 
+Debugging options:
+  --debug-tests            Log testing activity to the PHPUnitCommand log channel.
+
 EOT;
        }
 }
diff --git a/tests/phpunit/MediaWikiPHPUnitTestListener.php b/tests/phpunit/MediaWikiPHPUnitTestListener.php
new file mode 100644 (file)
index 0000000..18e3fb7
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+class MediaWikiPHPUnitTestListener implements PHPUnit_Framework_TestListener {
+
+       /**
+        * @var string
+        */
+       protected $logChannel;
+
+       public function __construct( $logChannel ) {
+               $this->logChannel = $logChannel;
+       }
+
+       protected function getTestName( PHPUnit_Framework_Test $test ) {
+               $name = get_class( $test );
+
+               if ( $test instanceof PHPUnit_Framework_TestCase ) {
+                       $name .= '::' . $test->getName( true );
+               }
+
+               return $name;
+       }
+
+       protected function getErrorName( Exception $exception ) {
+               $name = get_class( $exception );
+               $name = "[$name] " . $exception->getMessage();
+
+               return $name;
+       }
+
+       /**
+        * An error occurred.
+        *
+        * @param  PHPUnit_Framework_Test $test
+        * @param  Exception              $e
+        * @param  float                  $time
+        */
+       public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               wfDebugLog( $this->logChannel, 'ERROR in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) );
+       }
+
+       /**
+        * 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 ) {
+               wfDebugLog( $this->logChannel, 'FAILURE in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) );
+       }
+
+       /**
+        * Incomplete test.
+        *
+        * @param  PHPUnit_Framework_Test $test
+        * @param  Exception              $e
+        * @param  float                  $time
+        */
+       public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) {
+               wfDebugLog( $this->logChannel, 'Incomplete test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) );
+       }
+
+       /**
+        * 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 ) {
+               wfDebugLog( $this->logChannel, 'Skipped test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) );
+       }
+
+       /**
+        * A test suite started.
+        *
+        * @param  PHPUnit_Framework_TestSuite $suite
+        * @since  Method available since Release 2.2.0
+        */
+       public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) {
+               wfDebugLog( $this->logChannel, 'START suite ' . $suite->getName() );
+       }
+
+       /**
+        * A test suite ended.
+        *
+        * @param  PHPUnit_Framework_TestSuite $suite
+        * @since  Method available since Release 2.2.0
+        */
+       public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) {
+               wfDebugLog( $this->logChannel, 'END suite ' . $suite->getName() );
+       }
+
+       /**
+        * A test started.
+        *
+        * @param  PHPUnit_Framework_Test $test
+        */
+       public function startTest( PHPUnit_Framework_Test $test ) {
+               wfDebugLog( $this->logChannel, 'Start test ' . $this->getTestName( $test ) );
+       }
+
+       /**
+        * A test ended.
+        *
+        * @param  PHPUnit_Framework_Test $test
+        * @param  float                  $time
+        */
+       public function endTest( PHPUnit_Framework_Test $test, $time ) {
+               wfDebugLog( $this->logChannel, 'End test ' . $this->getTestName( $test ) );
+       }
+}
\ No newline at end of file