-
-
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 multiple runs #4993
Comments
While I agree the design with the Facade and how it is currently implemented leaves room for improvements, I so far fail to see how either of your proposed changes would address the issue - at least as how I currently understand it:
As I understand your explanation above, you have multiple concurrent runs in parallel within the same application process - how ever that is achieved. How would resetting the state of the Facade help you after run? Each run would have to wait for the previous to complete - killing the very idea of paratest? What am I missing here?
Nitpicking alert: Technically, there is no Singleton. The Facade keeps track of the instance it created, which is not the same as a Singleton but of course the point of the Facade. Using DI would not change that. I'm afraid as of now I'm also not understanding (yet?) why that would be a major problem. The So where exactly is the problem when reaching the level of test execution? You should not add new listeners or tracers once testing started. For that reason, the sealing has been introduced. It only affects the registration of new listeners and tracers. Maybe I'm missing something very obvious but so far I do not see a problem? |
Multiple consecutive application runs run in the same process. It is the equivalent of writing such script: (new PHPUnit\TextUI\Application())->run(['phpunit', 'test/MyTest1.php'], false);
(new PHPUnit\TextUI\Application())->run(['phpunit', 'test/MyTest2.php'], false);
(new PHPUnit\TextUI\Application())->run(['phpunit', 'test/MyTest3.php'], false);
Sure it is not a Singleton strictly speaking, but it is a stateful static class, so it behaves like a Singleton
If you run the above example, the first test runs smoothly, but the second exits with the following error:
The optimal solution would be to remove every |
Sorry to keep you waiting, Filippo. In general, I am not a fan (quite the opposite, actually) of singletons, global state, etc. and agree with you that using dependency injection to make emitting events possible wherever needed. However, for this first iteration of the event system, which also has to deal with legacy test execution, I would prefer to stick with the current approach and revisit the situation when we have a new test runner (this is the next big improvement I want to work on after PHPUnit 10 has been shipped). In the meanwhile, I have no problem at all with implementing your "reset the Singleton after the run" suggestion. Please let me know if you would like to send a pull request for that. Otherwise I will implement it ASAP. |
Sorry, maybe I'm just blind or stupid - or it's still to early but I still fail to see the problem with the facade. I'm perfectly happy to admit the implementation is far from perfect and should probably get revisited. But as @Slamdunk describes with the consecutive calls of This all has nothing to do with the Facade. As I (currently?) see it we'd be fixing the wrong problem here.. |
It seems you've already in mind the best solution, so I'll leave it to you. The only thing that matters to me is the following test to pass: --TEST--
phpunit ../../_files/BankAccountTest.php
--FILE--
<?php declare(strict_types=1);
$_SERVER['argv'][] = '--do-not-cache-result';
$_SERVER['argv'][] = '--no-configuration';
$_SERVER['argv'][] = __DIR__ . '/../../_files/BankAccountTest.php';
require_once __DIR__ . '/../../bootstrap.php';
PHPUnit\TextUI\Application::main(false);
PHPUnit\TextUI\Application::main(false);
--EXPECTF--
PHPUnit %s by Sebastian Bergmann and contributors.
Runtime: %s
... 3 / 3 (100%)
Time: %s, Memory: %s
OK (3 tests, 3 assertions)
PHPUnit %s by Sebastian Bergmann and contributors.
Runtime: %s
... 3 / 3 (100%)
Time: %s, Memory: %s
OK (3 tests, 3 assertions) @theseer I don't think 3rd parties should reset the state: it's PHPUnit's duty to leave a clean state after run |
Valid point. I was actually somehow expecting it to be a That leaves the question, what do we consider a "run"? And why would we want to re-setup everything of the 2nd+ calls? With the risk of those being somehow different? |
I don't understand these two questions. At the end of |
See, that's where I'm not sure yet. And that would include a bunch of things done plus accompanying events that are useless to be redone and emitted again: Startup, Config handling, Facade Setup, Extension bootstrapping, .... as well as cleanup. As far as I understand it, we're trying to allow 3rd parties to trigger test execution. We do not need the aforementioned steps to be run again for every consecutive call ("run").
If we do as suggested, there is exactly no control from within PHPUnit to ensure it's exactly the same result. But maybe I'm still missing the point of all this.. |
Without what I'm asking here, dynamic (so non-preemptive) parallel test runs with a fixed number of long running parallel processes is impossible to achieve. And we need this in ParaTest to provide the fastest run possible for the entire test suite. And to be clear, the 20M downloads we have, already achieve this in PHPUnit 9, but V10 won't allow to in the current form |
I'm not arguing against what paratest is offering :) quite the opposite. Maybe we should have a short video call to discuss this in person to maybe resolve my confusion and find a not only a working solution but an optimal one :) |
The call just ended; we agreed to have a step back and discuss the problem instead of the solution.
This is currently not feasible in PHPUnit 10, but the proposed solution at #4996 doesn't suite the goal neither: it doesn't make any sense to set all the PHPUnit stuffs for every test, and forcing users to adopt a workaround to only have their bootstrap executed once is just bad. An idea would be to have sort of an API to easily call the bootstrapping operation and the test-run operation in two different steps, but further investigation is going to be done in the next sprint at the end of September. |
For the record: Implementing/Addressing Issue #5059 is a step in addressing this. |
Hi @sebastianbergmann and @theseer, I see that PHPUnit 10 is scheduled to be released in less than e month, on 2023-02-03. Tell me if I can be of any help to address this Issue on time ⏰ |
We have cleaned up Let us know whether this allows you to use PHPUnit's test runner from ParaTest. |
Just to stress some maybe obvious points:
I believe we can close this issue as the problem should no longer exist. If you disagree - or have any other questions, please comment. |
A far as I can tell, in the same process I still cannot call The issue doesn't seem to be solved right now 😕 |
Arne and I will look into this on Tuesday, stay tuned. |
We believe to be finished with refactoring / extracting code from the Please revisit and let us know if there are any problems left. |
Let me elaborate a bit: The For the actual running of tests,
A A While it is marked As Arne already mentioned, we believe that this addresses your problem and makes multiple runs possible. |
Summary
Hi, I'm the maintainer of ParaTest, a tool to run PHPUnit tests in parallel.
One way ParaTest can run is to spawn
$(nproc)
processes and run multiple tests within a single process.Multiple tests are called each with a separate
\PHPUnit\TextUI\Application::run
call withing the same process.This is a design choice that allow both:
$(nproc)
processesTo maximise the overall speed.
This design collides with the new Facade singleton in c853041, of which
seal
is never released after the run ends.So I'd like to ask:
The text was updated successfully, but these errors were encountered: