pytest-asyncio 有一个封闭的事件循环,但仅在运行所有测试时

Mat*_*son 23 pytest python-asyncio pytest-asyncio

我有一个测试来验证异步响应是否抛出异常,我正在使用 pytest-asyncio 版本 0.10.0 来运行该测试。

代码基本上是:

class TestThis:
    @pytest.mark.asyncio
    def test_the_thing(self):
       arg1 = "cmd"
       arg2 = "second command"
       with pytest.raises(CustomException):
           await do_thing(arg1, arg2)
Run Code Online (Sandbox Code Playgroud)

现在真正奇怪的是,如果我单独运行这个测试,或者单独运行这个类,这个测试就可以正常工作。但是,当我运行所有测试(项目根目录下的 pytest)时,每次都会失败并出现运行时错误,表示循环已关闭。

Rob*_*rcd 19

我不得不稍微调整一下 @matthewpark319 的答案,但session在工作中添加了 -scoped 固定装置conftest.py

import asyncio

import pytest


@pytest.fixture(scope="session")
def event_loop():
    try:
        loop = asyncio.get_running_loop()
    except RuntimeError:
        loop = asyncio.new_event_loop()
    yield loop
    loop.close()
Run Code Online (Sandbox Code Playgroud)

如果您使用的是pytest-asyncio,您可能还需要编辑pyproject.toml并添加:

[tool.pytest.ini_options]
asyncio_mode = "auto"
Run Code Online (Sandbox Code Playgroud)

  • `loop = asyncio.get_event_loop()` 在 Python 3.10 上产生一个 `DeprecationWarning: There is no current event loop`。https://docs.python.org/3.10/library/asyncio-eventloop.html#asyncio.get_event_loop (2认同)

Mat*_*ark 10

https://pypi.org/project/pytest-asyncio/

您显然可以覆盖 pytest-asyncio 的事件循环装置版本。他们是这样的:

@pytest.fixture
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop
    loop.close()
Run Code Online (Sandbox Code Playgroud)

我有这样的:

@pytest.fixture
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop
    cleanly_shutdown(loop)
Run Code Online (Sandbox Code Playgroud)

或者在其他情况下像这样:

@pytest.fixture
def event_loop():
    yield asyncio.get_event_loop()

def pytest_sessionfinish(session, exitstatus):
    asyncio.get_event_loop().close()
Run Code Online (Sandbox Code Playgroud)

这些文档非常有帮助:https://docs.pytest.org/en/latest/reference/reference.html ?highlight=sessionfinish#pytest.hookspec.pytest_sessionfinish