pytest-twisted
pytest-twisted copied to clipboard
[Discussion] Customisibility for pytest-twisted
I have a fairly specific use case with my project:
I'm using both Twisted (with asyncioreactor setup) and native asyncio awaits somewhat interchangeably, but when it came to testing, I've gotten into troubles with pytest_twisted's and pytest_asyncio's incompatibility.
The issue is that when using pytest_twisted it becomes impossible for pytest_asyncio to make a new loop for every test, since it's basically running inside a global twisted loop.
So basically, for my use case I would want to have pytest-twisted applied only in tests I need it to be applied and making a separate loop for every test and getting rid of it after test is done.
I've dealt with this by doing some tinkering, which resulted in:
- introducing
pytest.mark.twistedthat is checked bypytest_pyfunc_callthat skips if the mark is absent; - adding a
--twisted-marked-onlycmdopt thatpytest_collection_modifyitemschecks and if it'sFalse(which it is by default to preserve current behaviour) adds thetwistedmark to any test that doesn't have it already; - adding a
--twisted-scopecmdopt and atwisted_greenlet_fixture_factoryfunction that is called inpytest_configurethat depending on the scope:- behaves as if it wasn't there (except the resulting fixture isn't autouse) if
scope="session"(default); - makes a fixture with the specified scope that
delstwisted.internet.reactorbefore and after creating a new reactor and mocks it with it's created reactor for the users otherwise;
- behaves as if it wasn't there (except the resulting fixture isn't autouse) if
- in
pytest_runtest_setupadding thetwisted_greenletfixture for every test that has thepytest.mark.twisted(like autouse, that you can opt out of :з ).
I'll make a pull request for it, but the real question is: Is it of any use for anybody except me and could this the direction the project goes in?
OK, so after some more testing, any scope beside session doesn't work well at all. If something in the test-suite imports reactor indirectly at module level it can get hold of the wrong reactor. + the deal with it being a singleton and trying to force in to not be one ends up very messy and questionable. As I can see, it's a design-choice of Twisted, that we just have to live with..
So 3 ends up useless, but 1,2 and 4 look like a good idea to me, since it gives more control to the user over which tests are for twisted and which are not.
@tyerq, I can't promise I have a lot of time for this but I would be interested in seeing the PR. More compatibility is good, we'll just have to look at what it takes to get it.
We already have to decorate inlineCallbacks tests and async/await tests. You are using pytest.mark.twisted for regular function tests which are using deferreds directly?