python-3.x Pytest顺序测试A,然后测试B,再测试A

n9vozmp4  于 2023-03-04  发布在  Python
关注(0)|答案(1)|浏览(194)

是否可以按照这样的顺序进行测试:测试A将首先进行,然后测试B进行,然后测试A将再次作为第三个进行?
技术堆栈:Python 3.8.5pytest 6.1.0pytest订单1.0.1
下面是使用的代码:

import logging
import pytest

@pytest.mark.order(2)
def test_a():
    logging.info('test_a')
    pass

@pytest.mark.order(1)
@pytest.mark.order(3)
def test_b():
    logging.info('test_b')
    pass

但是测试B没有执行第三次,因为有两个 * order * 标记,所以只作为第一次执行了一次。

    • 输出:**

===================测试会话开始===============
收集...收集了2个项目
test.py::test_a PASSED [ 50%]
test.py::test_b PASSED [100%]
===================== 2次在0.07秒内通过================

3htmauhk

3htmauhk1#

实际上pytest-order不允许添加两个order标记。但是我为您想到了一些解决方案。
你可以使用pytest_generate_tests pytest钩子来解析这个语法,只需要把它添加到你的conftest.py文件中。
以下示例将读取所有pytest.mark.order标记,并对其进行参数化测试(如果提供了多个顺序标记)。它添加了名为order的参数,该参数存储pytest.mark.order中指定的参数。

    • 对照品py**
def _get_mark_description(mark):
    if mark.kwargs:
        return ", ".join([f"{k}={v}" for k, v in mark.kwargs.items()])
    elif mark.args:
        return f"index={mark.args[0]}"
    return mark

def pytest_generate_tests(metafunc):
    """
    Handle multiple pytest.mark.order decorators.

    Make parametrized tests with corresponding order marks.
    """
    if getattr(metafunc, "function", False):
        if getattr(metafunc.function, "pytestmark", False):
            # Get list of order marks
            marks = metafunc.function.pytestmark
            order_marks = [
                mark for mark in marks if mark.name == "order"
            ]
            if len(order_marks) > 1:
                # Remove all order marks
                metafunc.function.pytestmark = [
                    mark for mark in marks if mark.name != "order"
                ]
                # Prepare arguments for parametrization with order marks
                args = [
                    pytest.param(_get_mark_description(mark), marks=[mark])
                    for mark in order_marks
                ]
                if "order" not in metafunc.fixturenames:
                    metafunc.fixturenames.append("order")
                metafunc.parametrize('order', args)
    • 测试订单. py**
import pytest

@pytest.mark.order(6)
@pytest.mark.order(4)
def test_4_and_6():
    pass

@pytest.mark.order(5)
@pytest.mark.order(3)
@pytest.mark.order(1)
def test_1_3_and_5():
    pass

@pytest.mark.order(2)
def test_2():
    pass
    • pytest test_order.py -v输出**
collecting ... collected 6 items

test_order.py::test_1_3_and_5[index=1] 
test_order.py::test_2 
test_order.py::test_1_3_and_5[index=3] 
test_order.py::test_4_and_6[index=4] 
test_order.py::test_1_3_and_5[index=5] 
test_order.py::test_4_and_6[index=6]

如您所见,所有测试都按照定义的顺序运行。

    • 统一采购司**

我已经更新了hook,使它与pytest-order的其他特性兼容。另外,我还创建了PR in pytest-order GitHub repo

相关问题