Message: add strict type to protected Message::$language
[mediawiki.git] / tests / phpunit / MediaWikiLoggerPHPUnitExtension.php
blobf414c9de202acd31b94f8c300df5153f27a41601
1 <?php
3 use MediaWiki\Logger\LogCapturingSpi;
4 use MediaWiki\Logger\LoggerFactory;
5 use MediaWiki\Logger\Spi;
6 use PHPUnit\Runner\AfterIncompleteTestHook;
7 use PHPUnit\Runner\AfterRiskyTestHook;
8 use PHPUnit\Runner\AfterSkippedTestHook;
9 use PHPUnit\Runner\AfterSuccessfulTestHook;
10 use PHPUnit\Runner\AfterTestErrorHook;
11 use PHPUnit\Runner\AfterTestFailureHook;
12 use PHPUnit\Runner\AfterTestHook;
13 use PHPUnit\Runner\AfterTestWarningHook;
14 use PHPUnit\Runner\BeforeTestHook;
16 /**
17 * Replaces the logging SPI on each test run. This allows another component
18 * (the printer) to fetch the logs when reporting why a test failed.
20 * Also logs test start and end messages to the original log.
22 class MediaWikiLoggerPHPUnitExtension implements
23 BeforeTestHook,
24 AfterRiskyTestHook,
25 AfterIncompleteTestHook,
26 AfterSkippedTestHook,
27 AfterSuccessfulTestHook,
28 AfterTestErrorHook,
29 AfterTestWarningHook,
30 AfterTestFailureHook,
31 AfterTestHook
33 /**
34 * @var string[]
35 * @todo Can we avoid global state?
37 public static $testsCollection;
38 /** @var Spi|null */
39 private $originalSpi;
40 /** @var Spi|null */
41 private $spi;
43 /**
44 * @inheritDoc
46 public function executeBeforeTest( string $test ): void {
47 $this->originalSpi = LoggerFactory::getProvider();
48 $this->spi = new LogCapturingSpi( $this->originalSpi );
49 LoggerFactory::registerProvider( $this->spi );
50 $this->log( "Start test $test" );
53 /** @inheritDoc */
54 public function executeAfterRiskyTest( string $test, string $message, float $time ): void {
55 $this->augmentTestWithLogs( $test );
58 /** @inheritDoc */
59 public function executeAfterIncompleteTest( string $test, string $message, float $time ): void {
60 $this->augmentTestWithLogs( $test );
61 $this->log( "Incomplete test $test: $message" );
64 /** @inheritDoc */
65 public function executeAfterSkippedTest( string $test, string $message, float $time ): void {
66 $this->augmentTestWithLogs( $test );
67 $this->log( "Skipped test $test: $message" );
70 /** @inheritDoc */
71 public function executeAfterTestError( string $test, string $message, float $time ): void {
72 $this->augmentTestWithLogs( $test );
73 $this->log( "ERROR in test $test: $message" );
76 /** @inheritDoc */
77 public function executeAfterTestWarning( string $test, string $message, float $time ): void {
78 $this->log( "Warning in test $test: $message" );
79 $this->augmentTestWithLogs( $test );
82 /** @inheritDoc */
83 public function executeAfterTestFailure( string $test, string $message, float $time ): void {
84 $this->log( "FAILURE in test $test: $message" );
85 $this->augmentTestWithLogs( $test );
88 private function augmentTestWithLogs( string $test ) {
89 if ( $this->spi && getenv( 'PHPUNIT_LOGS' ) !== '0' ) {
90 $logs = $this->spi->getLogs();
91 $formatted = $this->formatLogs( $logs );
92 self::$testsCollection[$test] = $formatted;
96 /** @inheritDoc */
97 public function executeAfterSuccessfulTest( string $test, float $time ): void {
98 $this->log(
99 sprintf( "Successful test %s, completed in %.6f seconds",
100 $test, $time ) );
103 /** @inheritDoc */
104 public function executeAfterTest( string $test, float $time ): void {
105 LoggerFactory::registerProvider( $this->originalSpi );
106 $this->originalSpi = null;
107 $this->spi = null;
111 * Get string formatted logs generated during the last
112 * test to execute.
114 * @param array $logs
115 * @return string
117 private function formatLogs( array $logs ) {
118 $message = [];
119 foreach ( $logs as $log ) {
120 if ( $log['channel'] === 'PHPUnitCommand' ) {
121 // Don't print the log of PHPUnit events while running PHPUnit,
122 // because PHPUnit is already printing those already.
123 continue;
125 $message[] = sprintf(
126 '[%s] [%s] %s %s',
127 $log['channel'],
128 $log['level'],
129 $log['message'],
130 json_encode( $log['context'] )
133 return implode( "\n", $message );
136 private function log( $message ) {
137 $spi = $this->originalSpi ?: LoggerFactory::getProvider();
138 $logger = $spi->getLogger( 'PHPUnit' );
139 $logger->debug( $message );