allure-pytest:如何将条目插入到不存在的测试的魅力报告中

问题描述 投票:0回答:1

我正在使用 allure-pytest。我正在使用故事/标记来表示测试计划要求。我将标记列表添加到 pytest.ini 文件。在 conftest.py 中,我生成了一组尚未使用的标记。我想将每个缺失的标记作为跳过的测试添加到我的魅力报告中。有没有办法做到这一点?

我试过在 conftest.py 中创建测试

import pytest
import allure

import allure_commons
from allure_commons.model2 import TestResult, Status, Label, Parameter
from allure_commons.types import AttachmentType
from allure_commons.reporter import AllureReporter
from allure_commons.utils import uuid4

def pytest_collection_finish(session):
    # get all the available markers defined in pytest.ini
    marker_dict = session.config.getini('markers')
    markers = set(marker_dict)

    # get all the markers used in the collected tests
    used_markers = set()
    for item in session.items:
        used_markers.update(set([m.name for m in item.iter_markers()]))

    # find the markers defined in pytest.ini but not used in any of the tests
    unused_markers = markers - used_markers

    item = session.items[0]

    # add skipped tests for the unused markers
    if unused_markers and item:
        print(item.parent)
        for marker in unused_markers:
            print("adding skipped test: ", marker)
            args = marker.split(":")
            name = args[0]
            add_external_test_result(name, "skipped")

            session.items.append(create_skipped_test(name, marker)) # generates an error for missing config

            #skipped_test = pytest.Function(name=f"test_missing_{name}", parent=None, config=item.config) # generates an error for deprecated method
            #skipped_test = item.from_parent(parent=item.parent, name=f"test_missing_{name}")
            #skipped_test.add_marker(pytest.mark.skip(reason=f"No test created for marker({marker})"))
            #session.items.append(skipped_test) # generates an error for the method not existing in the parent

def create_skipped_test(name, marker):
    # create a dummy test function with a skipped marker
    @pytest.mark.skip(reason=f"unmarked marker: {name}")
    @pytest.mark.usefixtures() # add any necessary fixtures
    def test_dummy():
        pass

    # add the marker to the test function
    test_dummy = pytest.mark.parametrize(name, [marker])(test_dummy)

    return test_dummy
pytest allure
1个回答
0
投票

好吧,这非常棘手,但我认为我已经使用

pytest_generate_tests
钩子和
pytest_collection_modifyitems
钩子包装器实现了预期的行为。

首先,您需要在您的

test_dummy
目录中的某处添加
tests
,如下所示:

test_dummy.py

def test_dummy():
    pass

然后在 conftest.py 你应该定义以下钩子函数:

import pytest
from _pytest.mark import Mark


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_collection_modifyitems(items):
    # get all test_dummy instances (with each mark parameter)
    skip_tests = [item for item in items if item.originalname == "test_dummy"]
    # remove all test_dummy from items to prevent it's execution without skip mark
    items[:] = [item for item in items if item.originalname != "test_dummy"]
    # let all other pytest_collection_modifyitems filter items
    yield
    # get set of all used markers
    used_markers = set()
    for item in items:
        used_markers.update(set([m.name for m in item.iter_markers()]))

    for item in skip_tests:
        # get mark name from parameter name of test_dummy instance
        mark = item.name.rsplit("[")[-1][:-1]
        # if mark name is not in used markers set:
        if mark not in used_markers:
            # add test_dummy with this mark and skip mark to items list
            item.own_markers = [Mark(mark, (), {}), Mark("skip", (), {"reason": f"skip mark: `{mark}`"})]
            items.append(item)


def pytest_generate_tests(metafunc):
    """Generate parametrization for test_dummy instance using only custom markers from `pytest.ini`."""
    if metafunc.definition.name == "test_dummy":
        # get list of CUSTOM markers from pytest.ini (without pytest plugins builtins markers!)
        markers = set(mark.split(":", maxsplit=1)[0] for mark in metafunc.config._getini('markers'))
        # add mark parameter to function arguments
        if "mark" not in metafunc.fixturenames:
            metafunc.fixturenames.append("mark")
        metafunc.parametrize("mark", [pytest.param(mark) for mark in markers])

我在代码中添加了一些注释,因此您可以跟踪它的逻辑。

基本上,它使用每个自定义标记(在

pytest.ini
中定义)为 test_dummy 创建参数化。然后它将所有
test_dummy
实例存储在单独的列表中,并将它们从
items
.

中删除

在其他插件完成所有过滤(包括 pytest 标记过滤)后,它会获得已使用标记的列表。对于每个具有不在使用列表中的参数的

test_dummy
实例,我们添加
skip
标记和参数名称标记并将其添加到最终
items
列表。

例子:

我在 pytest.ini 中有以下标记:

smoke
regression
unit
.

我对每个标记都有一个测试。我跑

pytest -m smoke --alluredir results
.

这是 Allure 中的结果。

让我知道你的想法。这是你想要达到的目标吗?

© www.soinside.com 2019 - 2024. All rights reserved.