Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用测试标记/参数化的pythonic/pytest方法是什么?_Python_Pytest - Fatal编程技术网

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

使用测试标记/参数化的pythonic/pytest方法是什么?,python,pytest,Python,Pytest,我的想法是我有一套条件,比如:正、负、偶数、奇数 我有一系列测试,可以在这些条件的组合下运行(“正+偶数”或“负+奇数”) 但是我只想用每个条件的任何值运行一个测试。例如: 正+偶数: 二, 负+奇 -三, 在这个例子中,我想标记测试,所以pytest根据条件自动选择值,并且只运行一次测试 我在考虑为每个条件创建一个fixture,并将所有fixture传递给测试或使用pytest_generate_测试 这个例子几乎就是我想要的,但是我不希望对每个DB运行测试,而是希望它只运行一次,并且支持任

我的想法是我有一套条件,比如:正、负、偶数、奇数

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

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

正+偶数:

二,

负+奇

-三,

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

我在考虑为每个条件创建一个fixture,并将所有fixture传递给测试或使用pytest_generate_测试

这个例子几乎就是我想要的,但是我不希望对每个DB运行测试,而是希望它只运行一次,并且支持任何组合条件,比如('oracle'、'Db2'、'mysql')+any('win'、'linux')

你能告诉我更好的方法吗?它应该在复杂的fixture中实现,还是使用pytest标签plugin+addition解析/处理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测试时,它只选择一个满足条件的oracle db,并且只运行一次


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

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

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

e、 g

查找所有“组合” 您只需通过生成参数列表来扩展上述内容。e、 g

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
导入pytest
@pytest.mark.env('偶数','负')
def测试和(数字):
断言(数字<0)和数字%2==0
@pytest.mark.env('ODD','POSITIVE'))
def测试_减法(编号):
断言(编号>0)和编号%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
来自_pytest.python import Metafunc
随机输入
导入pytest
def pytest_generate_测试(metafunc:metafunc):
如果metafunc.fixturenames中的“number”:
对于metafunc.definition.iter_markers()中的标记:
如果marker.name==“env”:
number=random.randint(-10,10)*2
如果marker.args中的“奇数”:
数字+=1
如果marker.args中的“正值”:
如果数字<0:
数字*=-1
如果marker.args中的“负值”:
如果数字>0:
数字*=-1
metafunc.parametrize('number',[number],indirect=True,scope='function')
@pytest.fixture
def编号(请求):
返回请求.param

请提供一个或两个示例函数,以及此场景中的测试,以便我们更好地了解所需的行为。听起来很像@aws_peedient,我已经更新了示例,现在可以理解了吗?请检查更新的示例,我希望我详细描述了它。如果您想这样做,您可能确实想看看评论中提到的假设。@de1是否只允许运行一次,而不是从策略中选择范围?看起来像是文档中提到的。检查并“假设”
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