-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Allow extension to fail a test immediately after the test is executed #5226
Comments
With such an extension point, Mockery could also run independently from the MockeryPHPUnitIntegration trait. And do mock verification in an extension. |
The event system is intended to be read-only and with #5219 fixed, exceptions thrown in third-party subscribers no longer affect how tests are run or interpreted. |
Alright. So the only way to provide this functionality is always to use hooks inside the TestCase instead (via trait, abstract classes, etc)? |
This is not a use case the event system supports. The events emitted by PHPUnit are subscribed to by PHPUnit itself to report progress and test results on the command-line as well as to generate logfiles. The events emitted by PHPUnit can be subscribed to by third-party extensions for PHPUnit's test runner to implement custom logfile formats, for instance. But the event system cannot be used to change how tests are run or how their result should be interpreted. TL;DR: Yes, for your use case you have to implement a template method such as A test double library such as Mockery needs to do two things: it needs its expectations to be verified after the test has finished and it needs to communicate to PHPUnit the result of this verification making sure that it is correctly interpreted (as a failure, not as an error). For the latter, a clean way was implemented in #5201 for PHPUnit 10.1 that will be used by Prophecy. |
I need this very feature too: be able to do assertions in an Extension, for the whole test suite, without adding extra steps on each test. #5201 seems good only for a tool that extends TestCase. As suggested in phpspec/prophecy-phpunit#45 (comment), the solution is easy, if you accept to use final class MyListenerAssertingSomething implements \PHPUnit\Runner\Extension\Extension
{
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
{
$facade->registerSubscribers(
new class($this) implements FinishedSubscriber {
public function __construct(
private readonly MyListenerAssertingSomething $listener
) {
}
public function notify(Finished $event): void
{
$this->listener->endTest($event);
}
},
);
}
public function endTest(Finished $event): void
{
// [...]
if ($everythingsOk) {
return;
}
// Both Facade and Emitter are @internal, but YOLO
\PHPUnit\Event\Facade::emitter()->testFailed(
$event->test(),
ThrowableBuilder::from(new ExpectationFailedException('Something bad happened')),
null
);
}
} |
I'm trying to create an extension for PHPUnit 10 that runs immediately after the test is executed.
phpunit/src/Framework/TestCase.php
Line 623 in ddf1b95
Currently, only
PostConditionFinished
can be used for this. But this only works when the TestCase has anassertPostConditions
method. When that method is not defined, it will never callPostConditionFinished
.I want to be able to do extra assertions for a library that I'm working on. I don't want to require a trait or abstract TestCase that sets up this
assertPostConditions
method.When the assertions fail in my extension, they let the test fail, which is exactly what I want.
The benefit of running the extension immediately after
runTest()
is that any exception thrown by the extension, will be caught by this try/catch block:phpunit/src/Framework/TestCase.php
Lines 602 to 628 in ddf1b95
Another solution could be to introduce a new Event that would allow an extension to fail the test after the test was passed. This was also discussed here: phpspec/prophecy-phpunit#45 (comment)
References:
The text was updated successfully, but these errors were encountered: