Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffered TestDox printer #3417

Merged
merged 12 commits into from Nov 26, 2018
Merged
100 changes: 71 additions & 29 deletions src/Runner/TestSuiteSorter.php
Expand Up @@ -64,6 +64,35 @@ final class TestSuiteSorter
*/
private $cache;

/**
* @var array array<string> A list of normalized names of tests before reordering
*/
private $originalExecutionOrder = [];

/**
* @var array array<string> A list of normalized names of tests affected by reordering
*/
private $executionOrder = [];

public static function getTestSorterUID(Test $test): string
{
if ($test instanceof PhptTestCase) {
return $test->getName();
}

if ($test instanceof TestCase) {
$testName = $test->getName(true);

if (\strpos($testName, '::') === false) {
$testName = \get_class($test) . '::' . $testName;
}

return $testName;
}

return $test->getName();
}

public function __construct(?TestResultCacheInterface $cache = null)
{
$this->cache = $cache ?? new NullTestResultCache;
Expand All @@ -72,7 +101,7 @@ public function __construct(?TestResultCacheInterface $cache = null)
/**
* @throws Exception
*/
public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDependencies, int $orderDefects): void
public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDependencies, int $orderDefects, bool $isRootTestSuite = true): void
{
$allowedOrders = [
self::ORDER_DEFAULT,
Expand All @@ -98,9 +127,13 @@ public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDepend
);
}

if ($isRootTestSuite) {
$this->originalExecutionOrder = $this->calculateTestExecutionOrder($suite);
}

if ($suite instanceof TestSuite) {
foreach ($suite as $_suite) {
$this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects);
$this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects, false);
}

if ($orderDefects === self::ORDER_DEFECTS_FIRST) {
Expand All @@ -109,6 +142,20 @@ public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDepend

$this->sort($suite, $order, $resolveDependencies, $orderDefects);
}

if ($isRootTestSuite) {
$this->executionOrder = $this->calculateTestExecutionOrder($suite);
}
}

public function getOriginalExecutionOrder(): array
{
return $this->originalExecutionOrder;
}

public function getExecutionOrder(): array
{
return $this->executionOrder;
}

private function sort(TestSuite $suite, int $order, bool $resolveDependencies, int $orderDefects): void
Expand Down Expand Up @@ -139,7 +186,7 @@ private function addSuiteToDefectSortOrder(TestSuite $suite): void
$max = 0;

foreach ($suite->tests() as $test) {
$testname = $this->getNormalizedTestName($test);
$testname = self::getTestSorterUID($test);

if (!isset($this->defectSortOrder[$testname])) {
$this->defectSortOrder[$testname] = self::DEFECT_SORT_WEIGHT[$this->cache->getState($testname)];
Expand Down Expand Up @@ -205,8 +252,8 @@ function ($left, $right) {
*/
private function cmpDefectPriorityAndTime(Test $a, Test $b): int
{
$priorityA = $this->defectSortOrder[$this->getNormalizedTestName($a)] ?? 0;
$priorityB = $this->defectSortOrder[$this->getNormalizedTestName($b)] ?? 0;
$priorityA = $this->defectSortOrder[self::getTestSorterUID($a)] ?? 0;
$priorityB = $this->defectSortOrder[self::getTestSorterUID($b)] ?? 0;

if ($priorityB <=> $priorityA) {
// Sort defect weight descending
Expand All @@ -226,7 +273,7 @@ private function cmpDefectPriorityAndTime(Test $a, Test $b): int
*/
private function cmpDuration(Test $a, Test $b): int
{
return $this->cache->getTime($this->getNormalizedTestName($a)) <=> $this->cache->getTime($this->getNormalizedTestName($b));
return $this->cache->getTime(self::getTestSorterUID($a)) <=> $this->cache->getTime(self::getTestSorterUID($b));
}

/**
Expand All @@ -252,7 +299,7 @@ private function resolveDependencies(array $tests): array
do {
$todoNames = \array_map(
function ($test) {
return $this->getNormalizedTestName($test);
return self::getTestSorterUID($test);
},
$tests
);
Expand All @@ -268,28 +315,6 @@ function ($test) {
return \array_merge($newTestOrder, $tests);
}

/**
* @param DataProviderTestSuite|TestCase $test
*
* @return string Full test name as "TestSuiteClassName::testMethodName"
*/
private function getNormalizedTestName($test): string
{
if ($test instanceof TestSuite && !($test instanceof DataProviderTestSuite)) {
return $test->getName();
}

if ($test instanceof PhptTestCase) {
return $test->getName();
}

if (\strpos($test->getName(), '::') !== false) {
return $test->getName(true);
}

return \get_class($test) . '::' . $test->getName(true);
}

/**
* @param DataProviderTestSuite|TestCase $test
*
Expand All @@ -312,4 +337,21 @@ function ($name) use ($testClass) {

return $names;
}

private function calculateTestExecutionOrder(Test $suite): array
{
$tests = [];

if ($suite instanceof TestSuite) {
foreach ($suite->tests() as $test) {
if (!($test instanceof TestSuite)) {
$tests[] = self::getTestSorterUID($test);
} else {
$tests = \array_merge($tests, $this->calculateTestExecutionOrder($test));
}
}
}

return $tests;
}
}
7 changes: 7 additions & 0 deletions src/TextUI/TestRunner.php
Expand Up @@ -39,6 +39,7 @@
use PHPUnit\Util\Log\JUnit;
use PHPUnit\Util\Log\TeamCity;
use PHPUnit\Util\Printer;
use PHPUnit\Util\TestDox\CliTestDoxPrinter;
use PHPUnit\Util\TestDox\HtmlResultPrinter;
use PHPUnit\Util\TestDox\TextResultPrinter;
use PHPUnit\Util\TestDox\XmlResultPrinter;
Expand Down Expand Up @@ -203,6 +204,7 @@ public function doRun(Test $suite, array $arguments = [], bool $exit = true): Te
$sorter = new TestSuiteSorter($cache);

$sorter->reorderTestsInSuite($suite, $arguments['executionOrder'], $arguments['resolveDependencies'], $arguments['executionOrderDefects']);
$originalExecutionOrder = $sorter->getOriginalExecutionOrder();

unset($sorter);
}
Expand Down Expand Up @@ -309,6 +311,11 @@ public function doRun(Test $suite, array $arguments = [], bool $exit = true): Te
$arguments['columns'],
$arguments['reverseList']
);

if (isset($originalExecutionOrder) && ($this->printer instanceof CliTestDoxPrinter)) {
/* @var CliTestDoxPrinter */
$this->printer->setOriginalExecutionOrder($originalExecutionOrder);
}
}
}

Expand Down