asynctest icon indicating copy to clipboard operation
asynctest copied to clipboard

Provide functionality of ClockedTestCase outside of the class

Open Wesmania opened this issue 6 years ago • 3 comments

It would be very convenient if we could use the code for manually controlling event loop time within a plain test function as well (e.g. via some 'TimeSkipper' class that's also offered as a fixture). At first glance there doesn't seem to be anything special happening in the class to prevent that.

Wesmania avatar Sep 22 '18 19:09 Wesmania

Hi,

Thanks for you suggestion. Can you give an example of API/use in code demonstrating how you would use this feature?

In order to provide this feature, we need to patch and/or access to the internals of the loop implementation, that's why it's kept contained inside the ClockedTestCase class.

Martiusweb avatar Sep 25 '18 08:09 Martiusweb

I've been using it together with the event_loop fixture from pytest-asyncio.

I made a TimeSkipper class that takes an event loop in constructor and works with its internals just as ClockedTestCase does. Then I added a time_skipper fixture that takes the event_loop fixture, wraps it in a TimeSkipper instance and returns that instance. Tests can use this fixture to run advance, e.g.:

@pytest.mark.asyncio
async def test_foo(time_skipper):
    bar = Bar()
    f = asyncio.ensure_future(Bar.do_thing())
    await time_skipper.advance(10)
    assert f.done()

I admit I didn't do any thorough testing or check if event_loop fixture is suitable for playing around with internals. I just used it for a single test and verified that it works there.

Given that I'm playing around with pytest-asyncio, perhaps it would be more convenient to add this feature to its event_loop fixture instead?

Wesmania avatar Sep 25 '18 15:09 Wesmania

I noticed that my approach leads to deadlocks when used with exhaust_callbacks.

Wesmania avatar Sep 28 '18 19:09 Wesmania