繁体   English   中英

使用测试标记/参数化的 pythonic/pytest 方法是什么?

[英]What is the pythonic/pytest way to use tests tagging/parametrization?

这个想法是我有一组条件,例如:正、负、偶数、奇数。

我有一堆测试,可以在这些条件的组合下运行(“正+偶”或“负+奇”)

但我只想使用每个条件的任何值运行一个测试。 例如:

正+偶:

2

负+奇

-3

在这个例子中,我想标记测试,所以 pytest 会根据条件自动选择值并且只运行一次测试。

我正在考虑为每个条件创建一个夹具并将所有夹具传递给测试或使用 pytest_generate_tests。

http://doc.pytest.org/en/latest/example/parametrize.html#deferring-the-setup-of-parametrized-resources这个例子几乎是我想要的,但不是为每个数据库运行测试,我'希望它运行一次并支持像 any('oracle', 'Db2', 'mysql') + any('win', 'linux') 这样的组合条件。

你能建议这样做的最佳方式吗? 它应该在一个复杂的装置中实现还是使用 pytest-tags 插件+附加解析/处理 conftest.py 中的组合,或者还有其他方法

更新:

例子

@pytest.fixture(scope='function')
def connection(request):
    oracle_dbs = ['db1', 'db2', 'db3_19c']
    mysql_dbs = ['db1', 'db2', 'db3']
    connect = Create_connector(request.tag[0])
    if request.tag[1] == 'oracle':
        if and not request.tag[2]:
            connect.oracle(random.choice(oracle_dbs))
        else:
            connect.oracle(random.choice(db3_19c))
    if request.tag[1] == 'mysql':
        connect.mysql(random.choice(mysql_dbs))
    return connect

@pytest.mark.tag('any_os', 'any_db')
def test_run_any_query(connection):
    pass

@pytest.mark.tag('linux', 'oracle')
def test_run_query_lin_oracle(connection):
    pass

@pytest.mark.tag('linux', 'oracle', '19c')
def test_run_query_lin_oracle(connection):
    pass

解释:

1 测试,它通过标签找到一个合适的环境并且只运行测试一次,而不是所有组合

2 测试,它也找到了一个合适的环境(所以它可以是 ubuntu/debian/gentoo/etc 和任何 oracle 版本),但它仍然应该只运行一次。

3 test,它只选择一个满足条件的oracle db并且只运行一次

我可以在 pytest_generate_tests(metafunc) 函数中获得标记或标签吗?

您的问题似乎有两个问题:

参数化测试

正如您已经在问题中链接的那样,您可以参数化测试。

例如

import pytest


@pytest.mark.parametrize("db_name,os_name", [
    ("oracle", "win"),
    ("Db2", "linux")
])
def test_db_os_combinations(db_name: str, os_name: str):
    print("\ndb_name={db_name}, os_name={os_name}".format(
        db_name=db_name,
        os_name=os_name
    ))

查找所有“组合”

您可以通过生成参数列表来简单地扩展上述内容。 例如

import pytest


@pytest.mark.parametrize("db_name,os_name", [
    (db_name, os_name)
    for db_name in ['oracle', 'Db2', 'mysql']
    for os_name in ['win', 'linux']
])
def test_db_os_combinations(db_name: str, os_name: str):
    print("\ndb_name={db_name}, os_name={os_name}".format(
        db_name=db_name,
        os_name=os_name
    ))

它已完成如下:test_numbers.py:

import pytest

@pytest.mark.env('EVEN', 'NEGATIVE')
def test_sum(number):
    assert (number < 0) and number % 2 == 0


@pytest.mark.env('ODD', 'POSITIVE')
def test_substraction(number):
    assert (number > 0) and number % 2 == 1

conftest.py:

from _pytest.python import Metafunc
import random
import pytest


def pytest_generate_tests(metafunc: Metafunc):
    if 'number' in metafunc.fixturenames:
        for marker in metafunc.definition.iter_markers():
            if marker.name == 'env':
                number = random.randint(-10, 10) * 2
                if 'ODD' in marker.args:
                    number += 1
                if 'POSITIVE' in marker.args:
                    if number < 0:
                        number *= -1
                if 'NEGATIVE' in marker.args:
                    if number > 0:
                        number *= -1
                metafunc.parametrize('number', [number], indirect=True, scope='function')


@pytest.fixture
def number(request):
    return request.param

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM