Skip to content

Commit

Permalink
Refactor unsetting tests during TestSuite::run, for even faster destr…
Browse files Browse the repository at this point in the history
…uction of instances.

- Continuing on the destruction fix: The iterator also holds the array of tests. For tests with dataProviders, this results in not immediately destructing each Test, but only when the deeper TestSuite is done.
- Refactored cleanup tricks: Just do a first loop so we no longer need properties nor the iterator, and then array_shift as we go.
- Added test coverage.
  • Loading branch information
Maarten Scholder authored and sebastianbergmann committed Jun 20, 2024
1 parent 8afb89b commit 541fd37
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 24 deletions.
35 changes: 11 additions & 24 deletions src/Framework/TestSuite.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use const PHP_EOL;
use function array_keys;
use function array_map;
use function array_shift;
use function assert;
use function call_user_func;
use function class_exists;
Expand Down Expand Up @@ -348,38 +349,24 @@ public function run(): void
return;
}

/** @var Test[] $tests Local array, so we clear references to instances asap during the real loop. */
$tests = [];

foreach ($this as $test) {
$tests[] = $test;
}

$this->tests = [];
$this->groups = [];

while ($test = array_shift($tests)) {
if (TestResultFacade::shouldStop()) {
$emitter->testRunnerExecutionAborted();

break;
}

$test->run();

foreach (array_keys($this->tests) as $key) {
if ($test === $this->tests[$key]) {
unset($this->tests[$key]);

break;
}
}

if ($test instanceof TestCase || $test instanceof self) {
foreach ($test->groups() as $group) {
if (!isset($this->groups[$group])) {
continue;
}

foreach (array_keys($this->groups[$group]) as $key) {
if ($test === $this->groups[$group][$key]) {
unset($this->groups[$group][$key]);

break;
}
}
}
}
}

$this->invokeMethodsAfterLastTest($emitter);
Expand Down
47 changes: 47 additions & 0 deletions tests/unit/Framework/TestSuiteRunDestructsTestCaseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Depends;
use PHPUnit\Framework\Attributes\Small;
use PHPUnit\Framework\Attributes\TestWith;

#[CoversClass(TestSuite::class)]
#[Small]
final class TestSuiteRunDestructsTestCaseTest extends TestCase
{
private static int $destructsDone = 0;

public function __destruct()
{
self::$destructsDone++;
}

public function testFirstTest(): void
{
$this->assertSame(0, self::$destructsDone);
}

#[Depends('testFirstTest')]
public function testSecondTest(): void
{
$this->assertSame(1, self::$destructsDone);
}

#[Depends('testSecondTest')]
#[TestWith([2])]
#[TestWith([3])]
#[TestWith([4])]
public function testThirdTestWhichUsesDataProvider($numberOfTestsBeforeThisOne): void
{
$this->assertSame($numberOfTestsBeforeThisOne, self::$destructsDone);
}
}

0 comments on commit 541fd37

Please sign in to comment.