Skip to content

Allow selectively enabling entity change purging in the test env (POC) - #155

Open
HypeMC wants to merge 1 commit into
sofascore:1.xfrom
HypeMC:phpunit-extension
Open

HypeMC wants to merge 1 commit into
sofascore:1.xfrom
HypeMC:phpunit-extension

Conversation

@HypeMC

@HypeMC HypeMC commented Sep 17, 2026

Copy link
Copy Markdown
Member

Summary 📝

This PR adds support for disabling entity change purging by default and enabling it only where needed.

Generating purge requests on every flush can noticeably slow down large test suites, even though most tests never assert on them.

A new entity_change_purging configuration option can be used to disable this behavior, for example in the test environment:

when@test:
    purgatory:
        purger: in-memory
        entity_change_purging: false

A new PHPUnit extension and #[WithEntityChangePurging] attribute can then be used to enable purging only for specific test classes or methods:

#[WithEntityChangePurging]
public function testPurgePost(): void
{
    // ...
}

When used on a test class, entity change purging is enabled for all tests in that class. When used on a test method, it is enabled only for that test. In both cases, the configured default is restored afterwards.

The new EntityChangePurgeSwitcher can also be used directly through its enable(), disable() and reset() methods, for example to temporarily disable purging while loading fixtures.

Checklist ✅

  • Tests updated 🐛
  • Docs updated 📚
  • Changelog updated 📋
  • Breaking change ⚠️

@HypeMC HypeMC self-assigned this Sep 17, 2026
@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.03922% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 97.57%. Comparing base (a2481de) to head (e87a4f0).

Files with missing lines Patch % Lines
src/PHPUnit/Metadata/AttributeReader.php 93.33% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                1.x     #155      +/-   ##
============================================
+ Coverage     97.48%   97.57%   +0.08%     
- Complexity      522      550      +28     
============================================
  Files            65       68       +3     
  Lines          1432     1483      +51     
============================================
+ Hits           1396     1447      +51     
  Misses           36       36              
Flag Coverage Δ
8.1 96.35% <98.03%> (+0.12%) ⬆️
8.2 96.28% <98.03%> (+0.13%) ⬆️
8.3 96.08% <98.03%> (+0.13%) ⬆️
8.4 97.29% <98.03%> (+0.09%) ⬆️
8.5 97.29% <98.03%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

}
});

$facade->registerSubscriber(new class($reader) implements SkippedSubscriber {

@pkranjcecx pkranjcecx Sep 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a test method has #[WithEntityChangePurging] and setUp() calls markTestIncomplete(), the static override remains true. PHPUnit does not emit Finished in this case, so the next test without the attribute also has purging enabled, even though the configured default is false.

Reproduced on PHPUnit 12.5.35 and 13.3.3. Adding a MarkedIncompleteSubscriber that calls resetForTest() fixes the issue. This also needs a regression test that checks the switch state in an unannotated test following the incomplete setup.


public function notify(BeforeTestMethodErrored $event): void
{
PurgatoryExtension::resetForTestClass($event->testClassName(), $this->reader);

@pkranjcecx pkranjcecx Sep 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In PHPUnit 13, BeforeTestMethodErrored no longer has a testClassName() method. The interface_exists() guard passes, but when setUp() throws an exception, this subscriber produces an additional runner warning:

Call to undefined method
PHPUnit\Event\Test\BeforeTestMethodErrored::testClassName()

The subsequent ErroredSubscriber still resets the switch, so this reproduction does not leak state. However, the callback fails and adds a warning alongside the original setup error.

Replacing the call with $event->calledMethod()->className() fixes the issue, verified on PHPUnit 12.5.35 and 13.3.3. A regression test exercising the actual setup-error lifecycle would catch this difference between PHPUnit versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants