pytest异步函数作为parameterize参数的参数

3

我有一个异步函数,它异步计算url列表,并且我想使用parameterize为每个url生成一个异步测试,用于断言状态码。 我想做的事情类似于这样:

import pytest

@pytest.fixture
async def compute_urls():
    urls = await compute_urls_helper()
    return urls

@pytest.mark.asyncio 
@pytest.mark.parameterize('url',await compute_urls()) 
async def test_url(compute_urls,url):
    resp = await get_url(url)
    assert resp.status_code == 200

我知道在参数化内部使用'await'是不可能的,因此我希望听到这种操作的建议。

1个回答

0

您可以使用asyncio.run来创建一个事件循环,以计算参数:

import asyncio
from unittest.mock import AsyncMock
import pytest


async def compute_urls_helper():
    return ["stackoverflow.com", "jooj.com"]


async def get_url(url: str) -> AsyncMock:
    return AsyncMock(status_code=200)


@pytest.mark.asyncio
@pytest.mark.parametrize("url", asyncio.run(compute_urls_helper()))
async def test_url(url):
    resp = await get_url(url)
    assert resp.status_code == 200

然而,我不建议经常使用这种方法,因为在文档中所述

此函数(asyncio.run)始终创建一个新的事件循环,并在结束时关闭它。 它应该用作asyncio程序的主入口点,并且理想情况下只应调用一次。

因此,您可以创建一个会话范围的fixture,以便您可以重复使用包含每个url对象的fixture,如下所示:

import asyncio
from unittest.mock import AsyncMock
import pytest


async def compute_urls_helper():
    return ["google.com", "jooj.com"]

#Can be moved to conftest.py in the root of the project
@pytest.fixture(scope="session", params=asyncio.run(compute_urls_helper()))
def url(request):
    return request.param

async def get_url(url: str) -> AsyncMock:
    return AsyncMock(status_code=200)


@pytest.mark.asyncio
async def test_url(url):
    resp = await get_url(url)
    assert resp.status_code == 200

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接