diff options
Diffstat (limited to 'tests/phpunit/includes/phpunit7')
-rw-r--r-- | tests/phpunit/includes/phpunit7/speed-trap-listener.php | 306 | ||||
-rw-r--r-- | tests/phpunit/includes/phpunit7/testcase.php | 31 |
2 files changed, 337 insertions, 0 deletions
diff --git a/tests/phpunit/includes/phpunit7/speed-trap-listener.php b/tests/phpunit/includes/phpunit7/speed-trap-listener.php new file mode 100644 index 0000000000..60b61891dc --- /dev/null +++ b/tests/phpunit/includes/phpunit7/speed-trap-listener.php @@ -0,0 +1,306 @@ +<?php + +/** + * A PHPUnit TestListener that exposes your slowest running tests by outputting + * results directly to the console. + */ +class SpeedTrapListener implements PHPUnit_Framework_TestListener { + + /** + * Internal tracking for test suites. + * + * Increments as more suites are run, then decremented as they finish. All + * suites have been run when returns to 0. + * + * @var integer + */ + protected $suites = 0; + + /** + * Time in milliseconds at which a test will be considered "slow" and be + * reported by this listener. + * + * @var int + */ + protected $slowThreshold; + + /** + * Number of tests to report on for slowness. + * + * @var int + */ + protected $reportLength; + + /** + * Collection of slow tests. + * + * @var array + */ + protected $slow = array(); + + /** + * Construct a new instance. + * + * @param array $options + */ + public function __construct( array $options = array() ) { + $this->loadOptions( $options ); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError( PHPUnit\Framework\Test $test, Throwable $t, float $time ): void { + } + + /** + * A warning occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_Warning $e + * @param float $time + * @since Method available since Release 5.1.0 + */ + public function addWarning( PHPUnit\Framework\Test $test, PHPUnit\Framework\Warning $e, float $time ): void { + } + + /** + * 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, float $time ): void { + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest( PHPUnit\Framework\Test $test, Throwable $t, float $time ): void { + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest( PHPUnit\Framework\Test $test, Throwable $t, float $time ): void { + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addSkippedTest( PHPUnit\Framework\Test $test, Throwable $t, float $time ): void { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest( PHPUnit\Framework\Test $test ): void { + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest( PHPUnit\Framework\Test $test, float $time ): void { + if ( ! $test instanceof PHPUnit_Framework_TestCase ) { + return; + } + + $time = $this->toMilliseconds( $time ); + $threshold = $this->getSlowThreshold( $test ); + + if ( $this->isSlow( $time, $threshold ) ) { + $this->addSlowTest( $test, $time ); + } + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite( PHPUnit\Framework\TestSuite $suite ): void { + $this->suites++; + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite( PHPUnit\Framework\TestSuite $suite ): void { + $this->suites--; + + if ( 0 === $this->suites && $this->hasSlowTests() ) { + arsort( $this->slow ); // Sort longest running tests to the top + + $this->renderHeader(); + $this->renderBody(); + $this->renderFooter(); + } + } + + /** + * Whether the given test execution time is considered slow. + * + * @param int $time Test execution time in milliseconds + * @param int $slowThreshold Test execution time at which a test should be considered slow (milliseconds) + * @return bool + */ + protected function isSlow( $time, $slowThreshold ) { + return $time >= $slowThreshold; + } + + /** + * Stores a test as slow. + * + * @param PHPUnit_Framework_TestCase $test + * @param int $time Test execution time in milliseconds + */ + protected function addSlowTest( PHPUnit_Framework_TestCase $test, $time ) { + $label = $this->makeLabel( $test ); + + $this->slow[ $label ] = $time; + } + + /** + * Whether at least one test has been considered slow. + * + * @return bool + */ + protected function hasSlowTests() { + return ! empty( $this->slow ); + } + + /** + * Convert PHPUnit's reported test time (microseconds) to milliseconds. + * + * @param float $time + * @return int + */ + protected function toMilliseconds( $time ) { + return (int) round( $time * 1000 ); + } + + /** + * Label for describing a test. + * + * @param PHPUnit_Framework_TestCase $test + * @return string + */ + protected function makeLabel( PHPUnit_Framework_TestCase $test ) { + return sprintf( '%s:%s', get_class( $test ), $test->getName() ); + } + + /** + * Calculate number of slow tests to report about. + * + * @return int + */ + protected function getReportLength() { + return min( count( $this->slow ), $this->reportLength ); + } + + /** + * Find how many slow tests occurred that won't be shown due to list length. + * + * @return int Number of hidden slow tests + */ + protected function getHiddenCount() { + $total = count( $this->slow ); + $showing = $this->getReportLength( $this->slow ); + + $hidden = 0; + if ( $total > $showing ) { + $hidden = $total - $showing; + } + + return $hidden; + } + + /** + * Renders slow test report header. + */ + protected function renderHeader() { + echo sprintf( "\n\nYou should really fix these slow tests (>%sms)...\n", $this->slowThreshold ); + } + + /** + * Renders slow test report body. + */ + protected function renderBody() { + $slowTests = $this->slow; + + $length = $this->getReportLength( $slowTests ); + for ( $i = 1; $i <= $length; ++$i ) { + $label = key( $slowTests ); + $time = array_shift( $slowTests ); + + echo sprintf( " %s. %sms to run %s\n", $i, $time, $label ); + } + } + + /** + * Renders slow test report footer. + */ + protected function renderFooter() { + if ( $hidden = $this->getHiddenCount( $this->slow ) ) { + echo sprintf( '...and there %s %s more above your threshold hidden from view', $hidden == 1 ? 'is' : 'are', $hidden ); + } + } + + /** + * Populate options into class internals. + * + * @param array $options + */ + protected function loadOptions( array $options ) { + $this->slowThreshold = isset( $options['slowThreshold'] ) ? $options['slowThreshold'] : 500; + $this->reportLength = isset( $options['reportLength'] ) ? $options['reportLength'] : 10; + } + + /** + * Get slow test threshold for given test. A TestCase can override the + * suite-wide slow threshold by using the annotation @slowThreshold with + * the threshold value in milliseconds. + * + * The following test will only be considered slow when its execution time + * reaches 5000ms (5 seconds): + * + * <code> + * + * @slowThreshold 5000 + * public function testLongRunningProcess() {} + * </code> + * + * @param PHPUnit_Framework_TestCase $test + * @return int + */ + protected function getSlowThreshold( PHPUnit_Framework_TestCase $test ) { + $ann = $test->getAnnotations(); + + return isset( $ann['method']['slowThreshold'][0] ) ? $ann['method']['slowThreshold'][0] : $this->slowThreshold; + } +} diff --git a/tests/phpunit/includes/phpunit7/testcase.php b/tests/phpunit/includes/phpunit7/testcase.php new file mode 100644 index 0000000000..325c553eed --- /dev/null +++ b/tests/phpunit/includes/phpunit7/testcase.php @@ -0,0 +1,31 @@ +<?php + +require_once dirname( dirname( __FILE__ ) ) . '/abstract-testcase.php'; + +/** + * Defines a basic fixture to run multiple tests. + * + * Resets the state of the WordPress installation before and after every test. + * + * Includes utility functions and assertions useful for testing WordPress. + * + * All WordPress unit tests should inherit from this class. + */ +class WP_UnitTestCase extends WP_UnitTestCase_Base { + /** + * Asserts that a condition is not false. + * + * This method has been backported from a more recent PHPUnit version, as tests running on PHP 5.2 use + * PHPUnit 3.6.x. + * + * @since 4.7.4 + * + * @param bool $condition Condition to check. + * @param string $message Optional. Message to display when the assertion fails. + * + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertNotFalse( $condition, string $message = '' ): void { + self::assertThat( $condition, self::logicalNot( self::isFalse() ), $message ); + } +} |