Python测试框架pytest(26)测试报告Allure - 特性

2022-07-26 14:39:30 浏览数 (1)

Python测试框架pytest(26)

测试报告Allure

特性

目录

  • 1、Environment
    • 1.1、添加Environment
    • 1.2、解决配置文件被删的问题
  • 2、Categories
  • 3、allure.step()
    • 3.1、@allure.step()方式
    • 3.2、with allure.step()方式
  • 4、allure.attach
  • 5、@allure.description()
  • 6、@allure.title()
  • 7、@allure.link()
  • 8、@allure.issue()
  • 9、@allure.testcase()
  • 10、@allure.epic()/feature()/story()
  • 11、@allure.severity()

1、Environment

Environment 是环境变量,报告默认是没有任何变量参数的,是需要自己配置的。

1.1、添加Environment

通过创建 environment.properties 或者 environment.xml 文件,并把文件存放到测试结果的文件夹(执行脚本时,--alluredir 选项后指定的目录)。

例如:

代码语言:javascript复制
pytest -n auto --alluredir=allure

存放在allure文件夹里。

1、添加配置文件

方式一:environment.properties

文件内容:

代码语言:javascript复制
Browser=Chrome
Browser.Version=89.0.4389.128
Stand=Test
ApiUrl=127.0.0.1/login
python.Version=3.7.9

方式二:environment.xml

文件内容:

代码语言:javascript复制
<environment>
    <parameter>
        <key>Browser</key>
        <value>Chrome</value>
    </parameter>
    <parameter>
        <key>Browser.Version</key>
        <value>89.0.4389.128</value>
    </parameter>
    <parameter>
        <key>Stand</key>
        <value>Test</value>
    </parameter>
        <parameter>
        <key>ApiUrl</key>
        <value>127.0.0.1/login</value>
    </parameter>
        <parameter>
        <key>python.Version</key>
        <value>3.7.9</value>
    </parameter>
</environment>

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

3、报告展示效果:

注:environment.xml 方式,文件内容含中文时,报告显示正常。

注:environment.properties 方式,文件内容含中文时,报告显示乱码。

1.2、解决配置文件被删的问题

运行 pytest 生成 allure 报告时,有时候需要加参数 --clean-alluredir(清除之前的报告记录),而配置文件(environment.properties 或 environment.xml)也会被删除。

解决方法:

将配置文件(environment.properties 或 environment.xml)存放于项目根目录,运行报告之前,拷贝到报告目录里即可。

项目目录结构:

运行命令(配置文件 environment.properties)

代码语言:javascript复制
pytest test_case.py --alluredir=allure --clean-alluredir
cp environment.properties ./allure/environment.properties
allure serve allure

运行命令(配置文件 environment.xml)

代码语言:javascript复制
pytest test_case.py --alluredir=allure --clean-alluredir
cp environment.xml ./allure/environment.xml
allure serve allure

2、Categories

Categories 是分类(测试用例结果的分类)

默认情况下,有两类缺陷:

  • Product defects 产品缺陷(测试结果:failed)
  • Test defects 测试缺陷(测试结果:error/broken)

可以创建自定义缺陷分类,将 categories.json 文件添加到测试结果的目录即可(和 environment.properties 放同一个目录)。

categories.json 参数:

  • name:分类名称。
  • matchedStatuses:测试用例的运行状态,默认["failed", "broken", "passed", "skipped", "unknown"]。
  • messageRegex:测试用例运行的错误信息,默认是 .* ,是通过正则去匹配的。
  • traceRegex:测试用例运行的错误堆栈信息,默认是 .* ,是通过正则去匹配的。

categories.json文件内容:

代码语言:javascript复制
[
  {
    "name": "Ignored tests",
    "matchedStatuses": ["skipped"]
  },
  {
    "name": "Infrastructure problems",
    "matchedStatuses": ["broken", "failed"],
    "messageRegex": ".*signOut.*"
  },
  {
    "name": "Outdated tests",
    "matchedStatuses": ["broken"],
    "traceRegex": ".*FileNotFoundException.*"
  },
  {
    "name": "Product defects",
    "matchedStatuses": ["failed"]
  },
  {
    "name": "Test defects",
    "matchedStatuses": ["broken"]
  }
]

如图所示:测试用例报错时,显示效果

3、allure.step()

在 allure 报告中添加测试用例步骤有两种方式:

1、@allure.step() 这种方式会带上函数的传参和对应的值。

2、with allure.step() 这种方式代码可读性更好一点,但不会带上函数里面的传参和对应的值。

3.1、@allure.step()方式

allure 报告允许对每个测试用例进行非常详细的步骤说明,通过 @allure.step() 装饰器,可以让测试用例在 allure 报告中显示更详细的测试过程。

@allure.step() 只有一个参数,就是 title,输入标题内容,allure 报告上就会显示出来。

1、创建test_allure_step.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

@allure.step("第一步")
def step_one():
    pass

@allure.step("第二步")
def step_two_with_nested():
    step_three()

@allure.step("第三步")
def step_three():
    step_four_with_arguments(123456, 'AllTests')

@allure.step("第四步{0},{arg2}")
def step_four_with_arguments(arg1, arg2):
    pass

@allure.step("第五步")
def test_step_five():
    step_one()
    step_two_with_nested()

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

像Python字符串一样,支持位置参数和关键字参数

如:第四步{0},{arg2}

3.2、with allure.step()方式

1、创建test_allure_step2.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

def one():
    pass

def two_with_nested():
    three()

def three():
    pass

def four(arg1, arg2):
    pass

def five():
    one()
    two_with_nested()

def test_case():
    with allure.step("第一步"):
        one()

    with allure.step("第二步"):
        two_with_nested()

    with allure.step("第三步"):
        three()

    with allure.step("第四步"):
        four(arg1=123456, arg2='AllTests')

    with allure.step("第五步"):
        five()

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

执行第四步时,报告没有带上函数里面的传参和对应的值。

4、allure.attach

allure 报告可以显示许多不同类型的附件,这些附件可以补充测试、步骤或装置结果。

可以通过调用:

方式一:

allure.attach(body, name, attachment_type, extension)

参数:

  • body:要写入文件的原始内容。
  • name:附件名。
  • attachment_type:附件类型(是 allure.attachment_type 里面的其中一种)。
  • extension:所创建文件的扩展名。

allure.attachment_type提供的附件类型:

方式二:

allure.attach.file(source, name, attachment_type, extension)

参数:

source:包含文件路径的字符串。

(其他参数相同)

1、创建test_allure_attach.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest
import allure

@pytest.fixture
def attach_fixture_one(request):
    allure.attach('fixture前置操作,添加一个附件txt', 'fixture前置附件', allure.attachment_type.TEXT)

    def attach_fixture_two():
        allure.attach('fixture后置操作,添加一个附件txt', 'fixture后置附件', allure.attachment_type.TEXT)

    request.addfinalizer(attach_fixture_two)

def test_attach_fixture(attach_fixture_one):
    print("allure")

def test_attach_fixture_file():
    allure.attach('<head></head><body> a page </body>', 'page demo', allure.attachment_type.HTML)
    allure.attach.file('./demo.html', 'AllTests demo', attachment_type=allure.attachment_type.HTML)

创建demo.html文件(存放到项目的根目录上)

文件内容:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <title>软件测试</title>
  </head>
  <body>
    <h1>AllTests</h1>
  </body>
</html>

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

用例test_attach_fixture

用例test_attach_fixture_file,第一个附件为手写的HTML,第二个附件是导入的HTML文件。

5、@allure.description()

添加足够详细的测试用例描述,更加方便查看测试步骤。

三种方式:

代码语言:javascript复制
方式一:
@allure.description_html(str):传一个HTML代码组成的字符串

方式二:
@allure.description(str)

方式三:
在测试用例函数下方添加 """ """

1、创建test_allure_description.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

# 方式一
@allure.description_html("""
<h1>Test with some complicated html description</h1>
<table style="width:100%">
  <tr>
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Age</th>
  </tr>
  <tr align="center">
    <td>William</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr align="center">
    <td>Vasya</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
</table>
""")
def test_html_description():
    assert True

# 方式二
@allure.description("""
多行测试描述
这是一个@allure.description装饰器
""")
def test_description_from_decorator():
    assert 42 == int(6 * 7)

# 方式三
def test_unicode_in_docstring_description():
    """
    多行测试描述
    assert断言
    """
    assert 42 == int(6 * 7)

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

方式一:

方式二:

方式三:

6、@allure.title()

测试用例的标题可以通过特殊的方式变得更易读,标题支持参数占位符并支持动态替换。

示例一:

1、创建test_allure_title.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest
import allure

@allure.title("前置操作:登录")
@pytest.fixture
def test_login(request):
    params = request.param
    name = params["username"]
    pwd = params["pwd"]
    allure.attach(f"测试用例传的参数{params}")
    print(name, pwd, params)
    yield name, pwd

@allure.title("登录成功,测试数据:{test_login}")
@pytest.mark.parametrize("test_login", [{"username": "admin", "pwd": "123456"}, {"username": "root", "pwd": "root"}], indirect=True)
def test_login_success(test_login):
    name, pwd = test_login
    allure.attach(f"账号:{name},密码:{pwd}")

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

示例二:

1、创建test_allure_title2.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest
import allure

@allure.title("测试标题参数化: {param1}   {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

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

7、@allure.link()

链接(访问链接)

装饰器源码:

参数:

  • url:跳转的链接。
  • name:显示在 allure 报告的名字,如果不传就是显示完整的链接。

类似的装饰器:

Bug链接:@allure.issue()

测试用例链接:@allure.testcase()

1、创建test_allure_link.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

@allure.link('https://www.baidu.com/')
def test_with_link():
    pass

@allure.link('https://www.baidu.com/', name='百度一下')
def test_with_named_link():
    pass

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

无name参数

有name参数

8、@allure.issue()

链接(Bug链接)

装饰器源码:

调用link(),但link_type=LinkType.ISSUE。

参数:

  • url:跳转的链接。
  • name:显示在 allure 报告的名字,如果不传就是显示完整的链接。

类似的装饰器:

访问链接:@allure.link()

测试用例链接:@allure.testcase()

1、创建test_allure_issue.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

@allure.issue('https://www.baidu.com/')
def test_with_issue():
    pass

@allure.issue('https://www.baidu.com/', 'BUG链接')
def test_with_named_issue():
    pass

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

无name参数

有name参数

9、@allure.testcase()

链接(测试用例链接)

装饰器源码:

调用link(),但link_type=LinkType.TEST_CASE。

参数:

  • url:跳转的链接。
  • name:显示在 allure 报告的名字,如果不传就是显示完整的链接。

类似的装饰器:

访问链接:@allure.link()

Bug链接:@allure.issue()

1、创建test_allure_testcase.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

@allure.testcase('https://www.baidu.com/')
def test_with_testcase():
    pass

@allure.testcase('https://www.baidu.com/', '测试用例地址')
def test_with_named_testcase():
    pass

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

无name参数

有name参数

10、@allure.epic()/feature()/story()

allure 标记装饰器(可显示在测试报告上):

@allure.epic:敏捷里面的概念,定义史诗,往下是 feature。

@allure.feature:功能点的描述,理解成模块,往下是 story。

@allure.story:故事,往下是 title。

示例一:

1、创建test_allure_epic_feature_story.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

def test_without_any_annotations_that_wont_be_executed():
    pass

@allure.story('story1')
def test_with_story1():
    pass

@allure.story('story2')
def test_with_story2():
    pass

@allure.feature('feature3')
@allure.story('story3')
def test_with_feature3_story3():
    pass

@allure.epic('epic4')
@allure.feature('feature4')
@allure.story('story4')
def test_with_epic4_feature4_story4():
    pass

@allure.epic('epic5')
@allure.feature('feature5')
class TestCase:
    @allure.story('story5_1')
    def test_with_story5_1(self):
        print("执行 test_with_story5_1")

    @allure.story('story5_2')
    def test_with_story5_2(self):
        print("执行 test_with_story5_2")

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

首页FEATURES BY STORIES区域显示所设置的标记

Behaviors栏目下,带有标记的测试用例显示的标记层次顺序

示例二:命令行运行,指定运行某个标记(epic、feature、story)

命令行参数:

  • --allure-epics
  • --allure-features
  • --allure-stories

1、创建test_allure_epic_feature_story2.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import pytest
import allure
import os

@pytest.fixture(scope="session")
def login_fixture():
    print("===前置操作-登陆===")

@allure.step("步骤1")
def step1():
    print("===操作步骤1===")

@allure.step("步骤2")
def step2():
    print("===操作步骤2===")

@allure.step("步骤3")
def step3():
    print("===操作步骤3===")

@allure.epic("总体描述1")
@allure.feature("测试模块1")
class TestCaseAll1:
    @allure.testcase("https://www.baidu.com/", "测试用例")
    @allure.issue("https://www.baidu.com/", "Bug链接")
    @allure.title("用例标题")
    @allure.story("story1")
    @allure.severity("critical")
    def test_case1(self, login_fixture):
        print("===测试用例1===")
        step1()
        step2()

    @allure.story("story2")
    def test_case2(self, login_fixture):
        print("===测试用例2===")
        step1()
        step3()

@allure.epic("总体描述2")
@allure.feature("测试模块2")
class TestCaseAll2:
    @allure.story("story3")
    def test_case3(self, login_fixture):
        print("===测试用例3===")
        step1()

    @allure.story("story4")
    def test_case4(self, login_fixture):
        print("===测试用例4===")
        step3()

if __name__ == '__main__':
    pytest.main(['-s', '-q', '--alluredir', './allure'])
    os.system('allure -c ./allure')
    os.system('allure serve ./allure')

2、运行结果:

(1)运行全部:

执行完成后,自动打开浏览器加载测试报告

(2)命令行指定运行:

1)、只运行epic名为“总体描述1”的测试用例

代码语言:javascript复制
pytest --alluredir ./allure --allure-epics=总体描述1
allure serve allure

运行结果:

2)、只运行feature名为“测试模块2”的测试用例

代码语言:javascript复制
pytest --alluredir ./allure --allure-features=测试模块2
allure serve allure

运行结果:

3)、只运行story1、story3的测试用例(可以不用=号 空格也可以)

代码语言:javascript复制
pytest --alluredir ./allure test_allure_epic_feature_story2.py --allure-stories story1,story3
allure serve allure

运行结果:

4)运行指定的feature story的测试用例(可以不用=号 空格也可以)

代码语言:javascript复制
pytest --alluredir ./allure test_allure_epic_feature_story2.py --allure-features 测试模块2 --allure-stories story2
allure serve allure

运行结果:

11、@allure.severity()

用来标记用例级别。

Allure 提供的用例等级:

  • BLOCKER = 'blocker' 阻塞缺陷(功能未实现,无法下一步)
  • CRITICAL = 'critical' 严重缺陷(功能点缺失)
  • NORMAL = 'normal' 一般缺陷(边界情况,格式错误)
  • MINOR = 'minor' 次要缺陷(界面错误与UI需求不符)
  • TRIVIAL = 'trivial 轻微缺陷(必须项无提示,或者提示不规范等)

一、示例:

1、创建test_allure_severity.py文件

脚本代码:

代码语言:javascript复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
微信公众号:AllTests软件测试
"""

import allure

def test_with_no_severity():
    pass

@allure.severity(allure.severity_level.BLOCKER)
def test_with_blocker_severity():
    pass

@allure.severity(allure.severity_level.CRITICAL)
def test_with_critical_severity():
    pass

@allure.severity(allure.severity_level.MINOR)
def test_with_minor_severity():
    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):
        """
        测试类优先级 normal
        """
        print("测试类优先级 normal")

    @allure.severity(allure.severity_level.CRITICAL)
    def test_inside_the_normal_severity_test_class_with_overriding_critical_severity(self):
        """
        测试类优先级 normal
        测试用例优先级 critical
        """
        print("测试类优先级 normal;测试用例优先级 critical")

@allure.severity("normal")
def test_case_1():
    """ normal 级别测试用例 """
    print("normal 级别测试用例")

@allure.severity("critical")
def test_case_2():
    """ critical 级别测试用例 """
    print("critical 级别测试用例")

@allure.severity("blocker")
def test_case_3():
    """ blocker 级别测试用例 """
    print("blocker 级别测试用例")

@allure.severity("minor")
def test_case_4():
    """ minor 级别测试用例 """
    print("minor 级别测试用例")

@allure.severity("trivial")
def test_case_5():
    """ trivial 级别测试用例 """
    print("trivial 级别测试用例")

def test_case_6():
    """ 未标记 severity 的用例默认为 normal """
    print("未标记 severity 的用例默认为 normal")

@allure.severity("normal")
def test_case_7():
    """ normal 级别测试用例 """
    assert (1 == 2)

@allure.severity("critical")
def test_case_8():
    """ critical 级别测试用例 """
    assert (1 == 2)

@allure.severity("blocker")
def test_case_9():
    """ blocker 级别测试用例 """
    assert (1 == 2)

2、输入命令运行:

代码语言:javascript复制
pytest -n auto --alluredir=allure
allure serve allure

运行结果:

Severity字段标记用例级别

图表里统计用例优先级

二、命令行参数运行:

根据优先级选择需要运行的测试用例

参数:

--allure-severities

例如:只运行severity=blocker、critical的测试用例,命令行输入

写法一:

代码语言:javascript复制
pytest test_allure_severity.py -sq --alluredir=allure --allure-severities=blocker,critical

写法二:

代码语言:javascript复制
pytest test_allure_severity.py -sq --alluredir=allure --allure-severities blocker,critical

运行结果:

按照需要运行的用例级别,运行了7条测试用例。

0 人点赞