运行 使用不同版本的夹具进行一项测试

Running one test with different versions of fixture

假设我有一个应用程序必须使用两个不同的后端:backend_1 和 backend_2。我有两个测试模块。

模块 test_backend_1.py:

@py.test.fixture(scope="session")
def backend_1():
    return connect_to_backend_1()

def test_contract_method_1(backend_1):
    result = run_contract_method_1()
    assert result == backend_1_method_1_get_data()

def test_contract_method_2(backend_1):
    result = run_contract_method_2()
    assert result == backend_1_method_2_get_data()

和test_backend_2.py:

@py.test.fixture(scope="session")
def backend_2():
    return connect_to_backend_2()

def test_contract_method_1(backend_2):
    result = run_contract_method_1()
    assert result == backend_2_method_1_get_data()

def test_contract_method_2(backend_2):
    result = run_contract_method_2()
    assert result == backend_2_method_2_get_data()

我想合并这两个模块,而不是提供具有相同接口的两个不同版本的夹具,运行我按顺序对每个模块进行测试。像这样:

@py.test.fixture(scope="session")
def backend():
    return [connect_to_backend_1(), connect_to_backend_2()]

def test_contract_method_1(backend):
    result = run_contract_method_1()
    assert result == backend_method_1_get_data()

def test_contract_method_2(backend):
    result = run_contract_method_2()
    assert result == backend_method_2_get_data()

注意:我必须有两个固定装置的 N 个版本(一个用于每种类型的后端):我的应用程序和本机后端连接器。如何使用 py.test?

我认为,在你的情况下,你可以使用 pytest.mark.parametrize 功能:

def backend1():
    return connect_to_backend_1()

def backend2():
    return connect_to_backend_2()

def backend3():
    return connect_to_backend_3()

..

def backendN():
    return connect_to_backend_N()


@pytest.mark.parametrize('backend', [
    backend1, backend2, backend3, 
    ..., backendN
])
def test_something(backend):
    result = run_contract_method_2()
    assert result == backend.method_2_get_data()

我认为参数化夹具非常适合您:

import pytest

@pytest.fixture
def backends():
    """Mapping of possible backend ids to their constructor functions."""
    return {
        1: connect_to_backend_1,
        2: connect_to_backend_2
    }

@pytest.fixture(scope="session", params=[1, 2])
def backend(request, backends):
    """Parametrized backend instance."""
    return backends[request.param]()

def test_contract_method_1(backend):
    result = run_contract_method_1()
    assert result == backend.get_data()

def test_contract_method_2(backend):
    result = run_contract_method_2()
    assert result == backend.get_data()

这还没有上线,但如果你完整地阅读了这篇文章,至少你会更好地理解它:

https://bitbucket.org/pytest-dev/pytest/src/da9d03b1f91d63ec97a989804bacfc03204b0e12/doc/en/fixture.txt?at=default