带有 pytest 的异步装置 [英] Async fixtures with pytest

查看:136
本文介绍了带有 pytest 的异步装置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何定义异步装置并在异步测试中使用它们?

How do I define async fixtures and use them in async tests?

以下代码都在同一个文件中,失败得很惨.测试运行程序是否明确调用了夹具而不是等待?

The following code, all in the same file, fails miserably. Is the fixture called plainly by the test runner and not awaited?

@pytest.fixture
async def create_x(api_client):
    x_id = await add_x(api_client)
    return api_client, x_id

async def test_app(create_x, auth):
    api_client, x_id = create_x
    resp = await api_client.get(f'my_res/{x_id}', headers=auth)
    assert resp.status == web.HTTPOk.status_code

生产

==================================== ERRORS ====================================
_____________ ERROR at setup of test_app[pyloop] ______________

api_client = <aiohttp.test_utils.TestClient object at 0x7f27ec954f60>

    @pytest.fixture
    async def create_x(api_client):
>       x_id = await add_x(api_client)
...
... cannot show the full trace and pathnames sorry
...    

in __await__
    ret = yield from self._coro /home/mbb/.pyenv/versions/3.6.3/envs/mr/lib/python3.6/site-packages/aiohttp/test_utils.py:245: in request
    method, self.make_url(path), *args, **kwargs /home/mbb/.pyenv/versions/mr/lib/python3.6/site-packages/aiohttp/helpers.py:104: in __iter__
    ret = yield from self._coro /home/mbb/.pyenv/versions/mr/lib/python3.6/site-packages/aiohttp/client.py:221: in _request
    with timer:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <aiohttp.helpers.TimerContext object at 0x7f27ec9875c0>

    def __enter__(self):
        task = current_task(loop=self._loop)

        if task is None:
>           raise RuntimeError('Timeout context manager should be used '
                               'inside a task') E           RuntimeError: Timeout context manager should be used inside a task

/home/mbb/.pyenv/versions/mr/lib/python3.6/site-packages/aiohttp/helpers.py:717: RuntimeError
=========================== 1 error in 1.74 seconds ============================ Process finished with exit code 0

我知道我可以做到

@pytest.fixture
def create_x(loop, api_client):
    x_id = loop.run_until_complete(add_x(api_client))
    return api_client, x_id

但我想知道是否存在更简单/最优雅的方法.我在 pytest、pytest-asyncio、pytest-aiohttp 的项目页面中都找不到清晰简单的示例/说明.

but I'd like to know if an easier/most elegant way exists. I cannot find a clear and simple example/explanation in the project pages of either pytest, pytest-asyncio, pytest-aiohttp.

我使用 Python 3.6.3、pytest 3.4.2、pytest-asyncio 0.8.0 和 pytest-aiohttp 0.3.0

I use Python 3.6.3, pytest 3.4.2, pytest-asyncio 0.8.0 and pytest-aiohttp 0.3.0

非常感谢您的帮助

推荐答案

你只需要将你的测试标记为异步

You only need to mark your tests as async

@pytest.mark.asyncio
async def test_app(create_x, auth):
    api_client, x_id = create_x
    resp = await api_client.get(f'my_res/{x_id}', headers=auth)
    assert resp.status == web.HTTPOk.status_code

这告诉 pytest 在事件循环中运行测试而不是直接调用它.

This tells pytest to run the test inside an event loop rather than calling it directly.

灯具可以标记为正常

@pytest.fixture
async def create_x(api_client):
    x_id = await add_x(api_client)
    return api_client, x_id

这篇关于带有 pytest 的异步装置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆