带有异步测试的 Pytest:之前和之后的测试设置

Gui*_*lva 3 python pytest python-asyncio

我使用 pytest 夹具的测试设置配置有问题:

@pytest.fixture(autouse=True)
async def run_around_tests(elastic_api, catalog):
    es_index_mapping = open('test/resources/es_index_mapping.json')
    es_index_mapping_dict = json.load(es_index_mapping)
    es_cars = open('test/resources/es_cars.json')
    es_cars_dict = json.load(es_cars)
    await elastic_api.create_index(index='catalog_test', payload=es_index_mapping_dict)
    await catalog.upsert_documents(index='catalog_test', payload=es_cars_dict)
    yield
    await elastic_api.delete_index(index='catalog_test')
    await catalog.close()
Run Code Online (Sandbox Code Playgroud)

似乎yield 没有正确执行并且没有等待测试执行。在测试执行期间发生elasticsearch索引的删除,导致测试失败。为什么只有在所有测试完成后才执行此删除?

Dun*_*nes 8

您用什么来驱动异步装置/测试?pytest 不能与 asyncio 一起开箱即用。如果您正在使用pytest-asyncio,那么您需要使用@pytest_asyncio.fixture而不是标准的来装饰您的灯具@pytest.fixture

测试您的夹具是否按预期工作的一个好方法是使用更简单的夹具并断言它正在产生正确的值。IE

import asyncio
import pytest
import pytest_asyncio

@pytest.fixture  # this decorator isn't quite smart enough to do the right thing
async def bad_fixture():
    await asyncio.sleep(0)
    yield 'bad_fixture_value'
    await asyncio.sleep(0)

@pytest.mark.asyncio
async def test_bad_fixture(bad_fixture):
    assert bad_fixture == 'bad_fixture_value'  # FAIL

@pytest_asyncio.fixture  # dedicated fixture decorator that will do the right thing
async def good_fixture():
    await asyncio.sleep(0)
    yield 'good_fixture_value'
    await asyncio.sleep(0)

@pytest.mark.asyncio
async def test_good_fixture(good_fixture):
    assert good_fixture == 'good_fixture_value'  # PASS
Run Code Online (Sandbox Code Playgroud)