Skip to content

Commit

Permalink
Refactoring WIP for persisting and testing of TestResultCache
Browse files Browse the repository at this point in the history
  • Loading branch information
Ewout Pieter den Ouden committed May 30, 2018
1 parent 0307a13 commit 0139690
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 83 deletions.
26 changes: 17 additions & 9 deletions src/Framework/ResultCacheListener.php
Expand Up @@ -9,6 +9,7 @@
*/
namespace PHPUnit\Framework;

use PHPUnit\Runner\TestResultCache;
use PHPUnit\Util\Printer;

class ResultCacheListener extends Printer implements TestListener
Expand All @@ -27,11 +28,20 @@ class ResultCacheListener extends Printer implements TestListener

private $runState = [];

/**
* @var TestResultCache
*/
private $cache;

public function __construct(?mixed $out = null)
{
$this->cache = new TestResultCache;
parent::__construct($out);
}

public function flush(): void
{
$cache = new \PHPUnit\Runner\TestResultCache();
$cache->loadFromListenerRunstate($this->runState);
$cache->persist();
$this->cache->persist();
}

public function addError(\PHPUnit\Framework\Test $test, \Throwable $t, float $time): void
Expand Down Expand Up @@ -73,10 +83,11 @@ public function endTest(\PHPUnit\Framework\Test $test, float $time): void
{
$testName = $this->fullTestName($test);

if ($this->runState[$testName]['state'] == self::TEST_START) {
if ($this->runState[$testName]['state'] === self::TEST_START) {
$this->runState[$testName]['state'] = self::TEST_PASSED;
}

$this->cache->setState($testName, $this->runState[$testName]['state']);
$this->calculateDuration($testName);
}

Expand All @@ -85,17 +96,15 @@ public function startTestSuite(\PHPUnit\Framework\TestSuite $suite): void
$suiteName = $suite->getName() ?? 'ROOT';

$this->runState[$suiteName] = [
'state' => self::SUITE_START,
'start' => \microtime(true),
'time' => 0
];
}

public function endTestSuite(\PHPUnit\Framework\TestSuite $suite): void
{
$suiteName = $suite->getName();
$suiteName = $suite->getName();

$this->runState[$suiteName]['state'] = self::SUITE_END;
$this->calculateDuration($suiteName);
}

Expand All @@ -120,8 +129,7 @@ private function updateRunState(\PHPUnit\Framework\Test $test, string $state): v
private function calculateDuration($name): void
{
if (isset($this->runState[$name]['start'])) {
$this->runState[$name]['time'] = \round(\microtime(true) - $this->runState[$name]['start'], 3);
unset($this->runState[$name]['start']);
$this->cache->setTime($name, \round(\microtime(true) - $this->runState[$name]['start'], 3));
}
}
}
71 changes: 32 additions & 39 deletions src/Util/TestResultCache.php
Expand Up @@ -17,7 +17,7 @@ class TestResultCache
/**
* @var string
*/
public const DEFAULT_RESULT_CACHE_FILENAME = 'phpunit.cache.json';
public const DEFAULT_RESULT_CACHE_FILENAME = 'phpunit.cache';

/**
* The list of defective tests
Expand Down Expand Up @@ -50,7 +50,7 @@ public function getResultCacheFilename()
public function persist(): void
{
if (isset($_ENV['PHPUNIT_RESULT_CACHE_SELFTEST'])) {
\var_dump($this->formatJSONOutputStruct());
\var_dump($this);

return;
}
Expand All @@ -62,37 +62,30 @@ public function saveToFile(): void
{
\file_put_contents(
$this->getResultCacheFilename(),
$this->formatJSONOutputStruct()
\serialize($this)
);
}

public function setState(string $testName, string $state): void
{
if ($state !== ResultCacheListener::TEST_PASSED) {
$this->defects[$testName] = $state;
}
}

public function getState($testName): string
{
return $this->defects[$testName] ?? ResultCacheListener::TEST_UNKNOWN;
}

public function getTime($testName): float
public function setTime(string $testName, float $time): void
{
return $this->times[$testName] ?? 0;
$this->times[$testName] = $time;
}

public function loadFromListenerRunstate(array $runState): void
public function getTime($testName): float
{
$this->clearCache();

// Only store tests with non-PASS results
$this->defects = \array_map(
function ($result) {
return $result['state'];
},
\array_filter($runState, function ($result) {
return !\in_array($result['state'], ['suite', 'passed'], true);
})
);

$this->times = \array_map(function ($result) {
return $result['time'];
}, $runState);
return $this->times[$testName] ?? 0;
}

public function loadFromFile(): void
Expand All @@ -103,38 +96,38 @@ public function loadFromFile(): void
return;
}

$json = \file_get_contents($this->getResultCacheFilename());
$cacheData = \file_get_contents($this->getResultCacheFilename());

if ($json === false) {
if ($cacheData === false) {
return;
}

$this->loadFromJSON($json);
$cache = \unserialize($cacheData);

if ($cache === false) {
return;
}

if ($cache instanceof self) {
/* @var \PHPUnit\Runner\TestResultCache */
$cache->copyStateToCache($this);
}
}

public function loadFromJSON(string $json)
public function copyStateToCache(self $targetCache): void
{
$cacheData = \json_decode($json, true);

if ($cacheData === null) {
return;
foreach ($this->defects as $name => $state) {
$targetCache->setState($name, $state);
}

$this->defects = $cacheData['defects'];
$this->times = $cacheData['times'];
foreach ($this->times as $name => $time) {
$targetCache->setTime($name, $time);
}
}

private function clearCache(): void
{
$this->defects = [];
$this->times = [];
}

private function formatJSONOutputStruct(): string
{
return \json_encode([
'defects' => $this->defects,
'times' => $this->times
], JSON_PRETTY_PRINT);
}
}
3 changes: 0 additions & 3 deletions tests/Framework/ResultCacheListenerTest.php
Expand Up @@ -127,9 +127,6 @@ public function testEmptySuite(): void
$suite->run($this->result);

$runState = [
'EmptyTestCaseTest' => [
'state' => ResultCacheListener::SUITE_END
],
'Warning' => [
'state' => ResultCacheListener::TEST_WARNING
]
Expand Down
11 changes: 5 additions & 6 deletions tests/Runner/TestSuiteSorterTest.php
Expand Up @@ -103,14 +103,13 @@ public function testSuiteSorterDefectsOptions(int $order, bool $resolveDependenc
$suite->addTestSuite(\MultiDependencyTest::class);

$cache = new TestResultCache();
$cache->loadFromListenerRunstate($runState);

$sorter = new TestSuiteSorter();
$_sorter = new \ReflectionClass($sorter);
$_cache = $_sorter->getProperty('cache');
$_cache->setAccessible(true);
$_cache->setValue($sorter, $cache);
foreach ($runState as $testName => $data) {
$cache->setState($testName, $data['state']);
$cache->setTime($testName, $data['time']);
}

$sorter = new TestSuiteSorter($cache);
$sorter->reorderTestsInSuite($suite, $order, $resolveDependencies, TestSuiteSorter::ORDER_DEFECTS_FIRST);

$this->assertEquals($expected, $this->getTestExecutionOrder($suite));
Expand Down
2 changes: 1 addition & 1 deletion tests/TextUI/defects-first-order-via-cli.phpt
Expand Up @@ -8,7 +8,7 @@ $_SERVER['argv'][3] = '--defects-first-order';
$_SERVER['argv'][4] = 'MultiDependencyTest';
$_SERVER['argv'][5] = __DIR__ . '/../_files/MultiDependencyTest.php';

$_ENV['PHPUNIT_RESULT_CACHE'] = __DIR__ . '/../_files/MultiDependencyTest_result_cache.json';
$_ENV['PHPUNIT_RESULT_CACHE'] = realpath(__DIR__ . '/../_files/MultiDependencyTest_result_cache.txt');

require __DIR__ . '/../bootstrap.php';
PHPUnit\TextUI\Command::main();
Expand Down
31 changes: 20 additions & 11 deletions tests/TextUI/execution-order-options-via-config.phpt
Expand Up @@ -23,17 +23,26 @@ Test 'MultiDependencyTest::testThree' started
Test 'MultiDependencyTest::testThree' ended
Test 'MultiDependencyTest::testFour' started
Test 'MultiDependencyTest::testFour' ended
string(%d) "{
"defects": [],
"times": {
"MultiDependencyTest": %f,
"testFive": %f,
"testTwo": %f,
"testOne": %f,
"testThree": %f,
"testFour": %f
}
}"
object(PHPUnit\Runner\TestResultCache)#10 (2) {
["defects":"PHPUnit\Runner\TestResultCache":private]=>
array(0) {
}
["times":"PHPUnit\Runner\TestResultCache":private]=>
array(6) {
["testFive"]=>
float(%f)
["testTwo"]=>
float(%f)
["testOne"]=>
float(%f)
["testThree"]=>
float(%f)
["testFour"]=>
float(%f)
["MultiDependencyTest"]=>
float(%f)
}
}


Time: %s, Memory: %s
Expand Down
13 changes: 0 additions & 13 deletions tests/_files/MultiDependencyTest_result_cache.json

This file was deleted.

3 changes: 2 additions & 1 deletion tests/_files/configuration_execution_order_defects.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit executionOrderDefects="defectsFirst">
<php>
<env name="PHPUNIT_RESULT_CACHE" value="tests/_files/MultiDependencyTest_result_cache.json"/>
<env name="PHPUNIT_RESULT_CACHE" value="tests/_files/MultiDependencyTest_result_cache.txt"/>
<env name="PHPUNIT_RESULT_CACHE_SELFTEST" value="true"/>
</php>
</phpunit>

0 comments on commit 0139690

Please sign in to comment.