I have two unit tests, if I run them one by one, they pass. If I run them at class level, one pass and the other one fails at response = await ac.post(
with the error message: RuntimeError: Event loop is closed
@pytest.mark.asyncio
async def test_successful_register_saves_expiry_to_seven_days(self):
async with AsyncClient(app=app, base_url="http://127.0.0.1") as ac:
response = await ac.post(
"/register/",
headers={},
json={
"device_id": "u1",
"device_type": DeviceType.IPHONE.value,
},
)
query = device.select(whereclause=device.c.id == "u1")
d = await db.fetch_one(query)
assert d.expires_at == datetime.utcnow().replace(
second=0, microsecond=0
) + timedelta(days=7)
@pytest.mark.asyncio
async def test_successful_register_saves_device_type(self):
async with AsyncClient(app=app, base_url="http://127.0.0.1") as ac:
response = await ac.post(
"/register/",
headers={},
json={
"device_id": "u1",
"device_type": DeviceType.ANDROID.value,
},
)
query = device.select(whereclause=device.c.id == "u1")
d = await db.fetch_one(query)
assert d.type == DeviceType.ANDROID.value
I have been trying for hours, what am I missing please?
UPDATE (>= 0.19.0)
Latest 0.19.0
of pytest-asyncio
has become strict
. You need now to change every @pytest.fixture
in the conftest.py
with @pytest_asyncio.fixture
.
These things keep changing too often.
UPDATE (< 0.19.0)
It is true that @pytest.yield_fixture
is deprecated. The proper way until version 0.19.0
is
@pytest.fixture(scope="session")
def event_loop(request):
loop = asyncio.get_event_loop()
yield loop
loop.close()
Original Answer:
I have found the solution.
Create a file named conftest.py
under tests
And insert the following:
@pytest.yield_fixture(scope="session")
def event_loop(request):
"""Create an instance of the default event loop for each test case."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
This will correctly end the loop after each test and allow multiple ones to be run.