如何在pytest中为asyncio代码编写fixture

how to write fixtures for asyncio code in pytest

我想将 asyncio 与 pytest 一起使用。

这是我想要做的:

我喜欢这样写测试代码:

def test_add(svr_fixture):
    await asyncio.sleep(100)
    assert m.add(1, 2) == 3   # I like the readability of this and want to restore it

我尝试用 pytest-asyncio (https://pypi.python.org/pypi/pytest-asyncio) 编写夹具,但不知道该怎么做。

这次测试我想出了什么(有效但看起来很笨拙并且掩盖了测试的意图):

def test_add():
    async def do_it():
        await asyncio.sleep(100)
        return m.add(1, 2)

    loop = asyncio.get_event_loop()
    coro = loop.create_server(server.ServerProtocol, '127.0.0.1', 8023)
    asyncio.async(coro)
    res = loop.run_until_complete(do_it())
    assert res == 3

任何有关如何将服务器代码提取到固定装置(如 link 文档或示例)的任何帮助都将不胜感激。

我认为不需要完整的服务器代码(但它在这里:

就像我在问题中指出的那样,我不希望异步内容使我的测试用例膨胀。到目前为止我能找到的唯一简单的工作解决方案是使用多处理。我知道 process.terminate() 不是结束异步循环的 "optimal way" 但至少它工作可靠。

# -*- coding: utf-8 -*-
import time
from multiprocessing import Process

import pytest
from my_server import server


@pytest.fixture
def fake_server():
    p = Process(target=server.run, args=())
    p.start()

    yield
    p.terminate()


def test_add2(fake_server):
    time.sleep(30)
    assert m.add(1, 2) == 3