Skip to content

Shared tests with hypothesis throws an Event loop is closed error #231

Closed
@gryevns

Description

@gryevns

When you have a class containing some shared tests (e.g. for contract testing between several implementations of an interface), and use both hypothesis and pytest-asyncio on the shared tests, pytest will raise an error when running the test for the second time.

HypothesisWorks/hypothesis#3122

Example

import hypothesis
import hypothesis.strategies
import pytest

class Shared:
    @pytest.mark.asyncio
    @hypothesis.given(value=hypothesis.strategies.integers())
    async def test_foo(self, value: int) -> None:
        assert value == value

class TestCaseOne(Shared):
    pass

class TestCaseTwo(Shared):
    pass
================================= test session starts ==================================
platform darwin -- Python 3.9.4, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /Users/garyevans/Projects/pytest-async-hypothesis
plugins: asyncio-0.16.0, hypothesis-6.23.3
collected 2 items                                                                      

test.py .F                                                                       [100%]

======================================= FAILURES =======================================
_________________________________ TestCaseTwo.test_foo _________________________________

self = <test.TestCaseTwo object at 0x1069abe20>

    @pytest.mark.asyncio
>   @hypothesis.given(value=hypothesis.strategies.integers())

test.py:8: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../Library/Caches/pypoetry/virtualenvs/pytest-async-hypothesis-BRvTXcHz-py3.9/lib/python3.9/site-packages/pytest_asyncio/plugin.py:191: in inner
    coro = func(**kwargs)
../../Library/Caches/pypoetry/virtualenvs/pytest-async-hypothesis-BRvTXcHz-py3.9/lib/python3.9/site-packages/pytest_asyncio/plugin.py:193: in inner
    task = asyncio.ensure_future(coro, loop=_loop)
../../.pyenv/versions/3.9.4/lib/python3.9/asyncio/tasks.py:667: in ensure_future
    task = loop.create_task(coro_or_future)
../../.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py:431: in create_task
    self._check_closed()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_UnixSelectorEventLoop running=False closed=True debug=False>

    def _check_closed(self):
        if self._closed:
>           raise RuntimeError('Event loop is closed')
E           RuntimeError: Event loop is closed

../../.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py:510: RuntimeError
-------------------------------------- Hypothesis --------------------------------------
Falsifying example: test_foo(
    value=0, self=<test.TestCaseTwo at 0x1069abe20>,
)
=============================== short test summary info ================================
FAILED test.py::TestCaseTwo::test_foo - RuntimeError: Event loop is closed
============================= 1 failed, 1 passed in 0.13s ==============================
sys:1: RuntimeWarning: coroutine 'Shared.test_foo' was never awaited

Environment

Package          Version
---------------- -------
hypothesis       6.23.3
pytest           6.2.5
pytest-asyncio   0.16.0

Workaround

If we modify the event_loop fixture and do not close the loop by default then the tests pass as expected.

@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions