Pytest集成Allure Report

目录

 

安装

用法

基本报告

支持 Pytest features

Xfail

条件标记

Fixtures and Finalizers

参数化

Allure Features

Steps

附件

描述

标题

重试

Tags

BDD 标签

严重性标记

Behave

安装

 使用

 Features

严重性

步骤和场景状态

步骤数据


安装


Pytest可从PyPI进行安装,因此建议使用pip进行安装。要安装最新版本,请从命令行执行:
 

$ pip install allure-pytest


这将安装allure pytest和allure python-commons包,以生成与allure2兼容的报告数据。如果第一代allure 报告使用的是以前版本的适配器,则需要首先卸载它。

用法

要使Allure侦听器能够在测试执行期间收集结果,只需添加--alluredir选项并提供应存储结果的文件夹的路径。例如:

$ pytest --alluredir=/tmp/my_allure_results

要在测试完成后查看实际报告,您需要使用Allure命令行实用程序根据结果生成报告。

$ allure serve /tmp/my_allure_results

此命令将在默认浏览器中显示生成的报告。

基本报告

您可以在Allure报告中看到所有默认的pytest状态:只有由于其中一个断言错误而未成功的测试才会被标记为失败,任何其他异常都会导致测试处于中断状态。

import pytest

def test_success():
    """this test succeeds"""
    assert True


def test_failure():
    """this test fails"""
    assert False


def test_skip():
    """this test is skipped"""
    pytest.skip('for a reason!')


def test_broken():
    raise Exception('oops')

支持 Pytest features

Allure报告支持的一些常见Pytest特性包括xfail、fixture和finalizer、标记、条件跳过和参数化。

Xfail


这是标记预期失败的pytest方法:(pytest文档)

@pytest.mark.xfail(condition=lambda: True, reason='this test is expecting failure')
def test_xfail_expected_failure():
    """this test is an xfail that will be marked as expected failure"""
    assert False


@pytest.mark.xfail(condition=lambda: True, reason='this test is expecting failure')
def test_xfail_unexpected_pass():
    """this test is an xfail that will be marked as unexpected success"""
    assert True

这导致测试被跳过,并在预期失败时用特殊标记进行标记。

Pytest集成Allure Report_第1张图片

以及描述中的特殊标记和意外通过时的特殊标签。

Pytest集成Allure Report_第2张图片

条件标记

在Pytest中,您可以有条件地将测试标记为在某些特定条件下不执行(Pytest docs):

@pytest.mark.skipif('2 + 2 != 5', reason='This test is skipped by a triggered condition in @pytest.mark.skipif')
def test_skip_by_triggered_condition():
    pass

当条件求值为true时,测试将在报告中接收“Skipped”状态、来自装饰器的标记和描述。

Pytest集成Allure Report_第3张图片

Fixtures and Finalizers

fixture和finalizer是Pytest将分别在测试开始前和测试结束后调用的实用函数。Allure跟踪每个fixture的调用,并详细显示调用了哪些方法和哪些参数,从而保留了正确的调用顺序。 (Pytest docs)

您不需要标记您的固定装置以使其在报告中可见,它们将自动检测到不同的skope。

@pytest.fixture(params=[True, False], ids=['param_true', 'param_false'])
def function_scope_fixture_with_finalizer(request):
    if request.param:
        print('True')
    else:
        print('False')
    def function_scope_finalizer():
        function_scope_step()
    request.addfinalizer(function_scope_finalizer)


@pytest.fixture(scope='class')
def class_scope_fixture_with_finalizer(request):
    def class_finalizer_fixture():
        class_scope_step()
    request.addfinalizer(class_finalizer_fixture)


@pytest.fixture(scope='module')
def module_scope_fixture_with_finalizer(request):
    def module_finalizer_fixture():
        module_scope_step()
    request.addfinalizer(module_finalizer_fixture)


@pytest.fixture(scope='session')
def session_scope_fixture_with_finalizer(request):
    def session_finalizer_fixture():
        session_scope_step()
    request.addfinalizer(session_finalizer_fixture)


class TestClass(object):

    def test_with_scoped_finalizers(self,
                                    function_scope_fixture_with_finalizer,
                                    class_scope_fixture_with_finalizer,
                                    module_scope_fixture_with_finalizer,
                                    session_scope_fixture_with_finalizer):
        step_inside_test_body()

Pytest集成Allure Report_第4张图片

根据夹具执行的结果,依赖它的测试可能会收到不同的状态。fixture中的异常将使所有依赖测试中断,pytest.skip()调用将使所有从属测试跳过。

import pytest

@pytest.fixture
def skip_fixture():
    pytest.skip()


@pytest.fixture
def fail_fixture():
    assert False


@pytest.fixture
def broken_fixture():
    raise Exception("Sorry, it's broken.")


def test_with_pytest_skip_in_the_fixture(skip_fixture):
    pass


def test_with_failure_in_the_fixture(fail_fixture):
    pass


def test_with_broken_fixture(broken_fixture):
    pass

Pytest集成Allure Report_第5张图片

参数化

您可以使用从输入参数集生成许多测试用例 @pytest.mark.parametrize. (Pytest docs)

所有参数名称和值都将在报告中捕获,也可以选择将参数名称替换为ids kwarg中提供的字符串描述。

import allure
import pytest


@allure.step
def simple_step(step_param1, step_param2 = None):
    pass


@pytest.mark.parametrize('param1', [True, False], ids=['id explaining value 1', 'id explaining value 2'])
def test_parameterize_with_id(param1):
    simple_step(param1)


@pytest.mark.parametrize('param1', [True, False])
@pytest.mark.parametrize('param2', ['value 1', 'value 2'])
def test_parametrize_with_two_parameters(param1, param2):
    simple_step(param1, param2)


@pytest.mark.parametrize('param1', [True], ids=['boolean parameter id'])
@pytest.mark.parametrize('param2', ['value 1', 'value 2'])
@pytest.mark.parametrize('param3', [1])
def test_parameterize_with_uneven_value_sets(param1, param2, param3):
    simple_step(param1, param3)
    simple_step(param2)

使用不同的命名和未命名参数集捕获的测试调用的示例。

Pytest集成Allure Report_第6张图片

具有命名参数的参数化测试的测试执行详细信息。

Pytest集成Allure Report_第7张图片

Allure Features

Allure目前几乎支持所有可用的功能,除了Pytest环境。

Steps

Allure报告的第一个可能也是最重要的方面是,它允许获得每个测试调用的非常详细的逐步表示。通过@allure.step decorator可以实现这一点,该decorator向报告添加了对带有所提供参数的注释方法或函数的调用。
用@step注释的方法可以存储在测试之外,并在需要时导入。步骤方法可以具有任意深度的嵌套结构。

import allure
import pytest

from .steps import imported_step


@allure.step
def passing_step():
    pass


@allure.step
def step_with_nested_steps():
    nested_step()


@allure.step
def nested_step():
    nested_step_with_arguments(1, 'abc')


@allure.step
def nested_step_with_arguments(arg1, arg2):
    pass


def test_with_imported_step():
    passing_step()
    imported_step()


def test_with_nested_steps():
    passing_step()
    step_with_nested_steps()

每个步骤的状态都显示在名称右侧的一个小图标中。嵌套步骤以树状可折叠结构进行组织。

Pytest集成Allure Report_第8张图片

步骤可以有一个描述行,该行支持传递的位置参数和关键字参数的占位符。关键字参数的默认参数也将被捕获。

import allure

@allure.step('Step with placeholders in the title, positional: "{0}", keyword: "{key}"')
def step_with_title_placeholders(arg1, key=None):
    pass


def test_steps_with_placeholders():
    step_with_title_placeholders(1, key='something')
    step_with_title_placeholders(2)
    step_with_title_placeholders(3, 'anything')

Pytest集成Allure Report_第9张图片

台阶也由固定装置支撑。下面是一个使用conftest.py模块中定义的fixture的测试示例(即使不直接导入,这样的fixture也会由Pytest解析):

conftest.py

import allure
import pytest


@allure.step('step in conftest.py')
def conftest_step():
    pass


@pytest.fixture
def fixture_with_conftest_step():
    conftest_step()
import allure

from .steps import imported_step


@allure.step
def passing_step():
    pass


def test_with_step_in_fixture_from_conftest(fixture_with_conftest_step):
    passing_step()

固定装置中的步骤显示在单独的树中,用于setup和teardown。

Pytest集成Allure Report_第10张图片

附件

报告可以显示提供的许多不同类型的附件,这些附件可以补充测试、步骤或夹具结果。附件可以通过调用诱惑来创建。attach(body,name,attachment_type,extension):

  1. body - 要写入文件的原始内容。

  2. name - 包含文件名的字符串

  3. attachment_type -attachment_type-allure.attachment_type值之一

  4. extension - 扩展名-将被用作创建文件的扩展名。

或allure.attach.file(源、名称、附件类型、扩展名):

  1. source - 包含文件路径的字符串。

(其他参数类似)

import allure
import pytest


@pytest.fixture
def attach_file_in_module_scope_fixture_with_finalizer(request):
    allure.attach('A text attacment in module scope fixture', 'blah blah blah', allure.attachment_type.TEXT)
    def finalizer_module_scope_fixture():
        allure.attach('A text attacment in module scope finalizer', 'blah blah blah blah',
                      allure.attachment_type.TEXT)
    request.addfinalizer(finalizer_module_scope_fixture)


def test_with_attacments_in_fixture_and_finalizer(attach_file_in_module_scope_finalizer):
    pass


def test_multiple_attachments():
    allure.attach.file('./data/totally_open_source_kitten.png', attachment_type=allure.attachment_type.PNG)
    allure.attach(' a page ', 'Attach with HTML type', allure.attachment_type.HTML)

附件显示在所属测试实体的上下文中。HTML类型的附件呈现并显示在报告页面上。这是一种方便的方式,可以为您自己的测试结果表示提供一些自定义。

Pytest集成Allure Report_第11张图片

描述

您可以添加测试的详细描述,以便根据需要为报表读取器提供尽可能多的上下文。这可以通过几种方式实现:您可以添加一个提供描述字符串的@allure.description装饰器,也可以使用@allre.description_html提供一些要在测试用例的“描述”部分中呈现的html。或者,描述将简单地从测试方法的文档字符串中提取。

import allure

@allure.description_html("""

Test with some complicated html description

Firstname Lastname Age
William Smith 50
Vasya Jackson 94
""") def test_html_description(): assert True @allure.description(""" Multiline test description. That comes from the allure.description decorator. Nothing special about it. """) def test_description_from_decorator(): assert 42 == int(6 * 7) def test_unicode_in_docstring_description(): """Unicode in description. Этот тест проверяет юникод. 你好伙计. """ assert 42 == int(6 * 7)

描述支持unicode字符串:

Pytest集成Allure Report_第12张图片

从description_HTML呈现的HTML:

Pytest集成Allure Report_第13张图片

此外,可以使用allure.dynamic.description从测试体内动态更新描述。

import allure

@allure.description("""
This description will be replaced at the end of the test.
""")
def test_dynamic_description():
    assert 42 == int(6 * 7)
    allure.dynamic.description('A final description.')
标题

使用特殊的@allure.title装饰器可以使测试标题更具可读性。标题支持参数占位符,并支持动态替换。

import allure
import pytest


@allure.title("This test has a custom title")
def test_with_a_title():
    assert 2 + 2 == 4


@allure.title("This test has a custom title with unicode: Привет!")
def test_with_unicode_title():
    assert 3 + 3 == 6


@allure.title("Parameterized test title: adding {param1} with {param2}")
@pytest.mark.parametrize('param1,param2,expected', [
    (2, 2, 4),
    (1, 2, 5)
])
def test_with_parameterized_title(param1, param2, expected):
    assert param1 + param2 == expected


@allure.title("This title will be replaced in a test body")
def test_with_dynamic_title():
    assert 2 + 2 == 4
    allure.dynamic.title('After a successful test finish, the title was replaced with this line.')

Pytest集成Allure Report_第14张图片

要将报告与错误跟踪器或测试管理系统集成,Allure具有@Allure.link、@Allure.issue和@Allure.testcase描述符。

import allure

TEST_CASE_LINK = 'https://github.com/qameta/allure-integrations/issues/8#issuecomment-268313637'


@allure.link('https://www.youtube.com/watch?v=4YYzUTYZRMU')
def test_with_link():
    pass


@allure.link('https://www.youtube.com/watch?v=Su5p2TqZxKU', name='Click me')
def test_with_named_link():
    pass


@allure.issue('140', 'Pytest-flaky test retries shows like test steps')
def test_with_issue_link():
    pass


@allure.testcase(TEST_CASE_LINK, 'Test case title')
def test_with_testcase_link():
    pass

@allure.link将在“链接”部分提供指向所提供url的可点击链接:

Pytest集成Allure Report_第15张图片

@allure.issue将提供一个带有小错误图标的链接。此描述符将测试用例id作为输入参数,以便将其与所提供的问题链接类型的链接模板一起使用。链接模板在Pytest的--plure链接模式配置选项中指定。必须使用冒号指定链接模板和类型:

$ pytest directory_with_tests/ --alluredir=/tmp/my_allure_report \
 --allure-link-pattern=issue:http://www.mytesttracker.com/issue/{}

模板关键字是issue、link和test_case,为相应类型的链接提供模板。

Pytest集成Allure Report_第16张图片

重试


诱惑允许您聚合关于在单个测试运行期间重新执行的测试的信息,以及一段时间内测试执行的历史记录。
对于重试,您可以使用Pytest重新运行失败插件。
例如,如果我们有一个非常不可靠的步骤方法,但经常失败,在Pytest启动选项中指定--reruns=5后,我们会在Retries选项卡上显示所有运行此测试的失败尝试。

import allure
import random
import time


@allure.step
def passing_step():
    pass


@allure.step
def flaky_broken_step():
    if random.randint(1, 5) != 1:
        raise Exception('Broken!')


def test_broken_with_randomized_time():
    passing_step()
    time.sleep(random.randint(1, 3))
    flaky_broken_step()

Pytest集成Allure Report_第17张图片

同样,这样的测试会在执行的测试列表中收到“片状”炸弹图标。

Tags

有时,您希望能够灵活地处理要执行的测试。Pytest通过使用标记[email protected](Pytest文档)来实现这一点。

Allure允许使用3种类型的标记装饰器以类似的方式标记测试,这些标记装饰器允许构建报告的表示:

  1. BDD风格的标记表示史诗、特色和故事

  2. 严重性标签

  3. 自定义标签

BDD 标签


有两个装饰器:@allure.feature和@allure.story,用于根据您项目的功能/故事细分来标记您的测试(有关背景信息,请参阅维基百科上的BDD文章)。要标记某个特征或故事属于史诗,请使用以epic_前缀开头的名称。
 

tests.py

import allure


def test_without_any_annotations_that_wont_be_executed():
    pass


@allure.story('epic_1')
def test_with_epic_1():
    pass


@allure.story('story_1')
def test_with_story_1():
    pass

@allure.story('story_2')
def test_with_story_2():
    pass


@allure.feature('feature_2')
@allure.story('story_2')
def test_with_story_2_and_feature_2():
    pass

您可以使用以下命令行选项指定要执行的不同测试集,并传递逗号分隔的值列表:

  1. --allure-epics

  2. --allure-features

  3. --allure-stories

例如:

$ pytest tests.py --allure-stories story_1,story_2

collected 5 items

tests.py ...                                                                    [100%]

============================== 3 passed in 0.01 seconds ==============================
$ pytest tests.py --allure-features feature2 --allure-stories story2

collected 5 items

tests.py ...                                                                     [100%]

=============================== 2 passed in 0.01 seconds ==============================
严重性标记

要按严重性级别标记测试,可以使用@allure.severity decorator。它以allure.severity_level枚举值为参数。

tests.py

import allure


def test_with_no_severity_label():
    pass


@allure.severity(allure.severity_level.TRIVIAL)
def test_with_trivial_severity():
    pass


@allure.severity(allure.severity_level.NORMAL)
def test_with_normal_severity():
    pass


@allure.severity(allure.severity_level.NORMAL)
class TestClassWithNormalSeverity(object):

    def test_inside_the_normal_severity_test_class(self):
        pass

    @allure.severity(allure.severity_level.CRITICAL)
    def test_inside_the_normal_severity_test_class_with_overriding_critical_severity(self):
        pass

Severity decorator可以应用于函数、方法或整个类。
通过使用带有逗号分隔的严重性级别列表的--plure severties命令行选项,将只运行具有相应严重性的测试。

$ pytest tests.py --allure-severities normal,critical

collected 5 items

bdd_annotations_demo/test_severity_labels.py ...                                [100%]

================================ 3 passed in 0.01 seconds ============================

Behave

诱惑与behavior集成为一个外部格式化程序。

安装

$ pip install allure-behave

 使用

您可以直接在命令行中指定格式化程序:

$ behave -f allure_behave.formatter:AllureFormatter -o %allure_result_folder% ./features

 Features

严重性

与严重性名称匹配的标签(如关键、琐碎等)将被解释为功能或场景严重性。如果没有提供,场景将继承功能严重性,或者在其他情况下覆盖它。如果存在多个严重性定义标记,则只使用最后一个。

步骤和场景状态

具有断言异常的步骤将被标记为失败。在测试执行过程中引发的其他异常将导致其状态被破坏。场景状态将由第一个不成功的步骤状态决定。当所有步骤都通过了,那么整个场景就被认为通过了。

步骤数据

步骤数据文本或表格数据在报告中表示为步骤附件

你可能感兴趣的:(python,数学建模,开发语言)