使用Allure生成漂亮的测试报告(上)

发表于:2021-1-05 10:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:secoder    来源:博客园

分享:
  Allure初识
  什么是Allure
  Allure 是由Qameta Software团队开源的一款旨在于解决让每个人能更容易生成并更简洁阅读的测试报告框架。它支持大多数的测试框架,如:Pytest、TestNG等,简单易用便于集成。
  Allure Framework是一种灵活的轻量级多语言测试报告工具,不仅可以以简洁的Web报告形式非常简洁地显示已测试的内容,也允许参与开发过程的每个人从日常测试中提取最大程度的有用信息
  从开发/质量保证的角度来看,Allure报告可以缩短常见缺陷的生命周期:可以将测试失败划分为bug和损坏的测试,还可以配置log,step,fixture,attachments,timings,历史记录以及与TMS的集成以及Bug跟踪系统,因此负责任的开发人员和测试人员将掌握所有信息
  从管理人员的角度来看,Allure提供了一个清晰的“全局”,涵盖了已涵盖的功能,缺陷聚集的位置,执行时间表的外观以及许多其他方便的事情
  Allure的模块化和可扩展性确保您始终能够微调某些东西,以使Allure更适合您
  唯一不足的就是,拓展功能需要在测试用例集上加装饰器
  配置环境
!pip3 install allure-pytest -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
Collecting allure-pytest
  Downloading http://pypi.doubanio.com/packages/9a/e3/9cea2cf25d8822752f55c9df16f0d0ef54ca6b369e3ccd0f51737f5288d3/allure_pytest-2.8.13-py3-none-any.whl
Collecting allure-python-commons==2.8.13 (from allure-pytest)
  Downloading http://pypi.doubanio.com/packages/21/4c/3fd196d82a31487d8cfc50a423de1dd0fb20128709a9b74e1e3d462dfb19/allure_python_commons-2.8.13-py3-none-any.whl
Collecting six>=1.9.0 (from allure-pytest)
  Downloading http://pypi.doubanio.com/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c6c5c1dba/six-1.14.0-py2.py3-none-any.whl
Collecting pytest>=4.5.0 (from allure-pytest)
  Downloading http://pypi.doubanio.com/packages/c7/e2/c19c667f42f72716a7d03e8dd4d6f63f47d39feadd44cc1ee7ca3089862c/pytest-5.4.1-py3-none-any.whl (246kB)
    100% |████████████████████████████████| 256kB 3.4MB/s ta 0:00:01
[?25hCollecting attrs>=16.0.0 (from allure-python-commons==2.8.13->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/a2/db/4313ab3be961f7a763066401fb77f7748373b6094076ae2bda2806988af6/attrs-19.3.0-py2.py3-none-any.whl
Collecting pluggy>=0.4.0 (from allure-python-commons==2.8.13->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/a0/28/85c7aa31b80d150b772fbe4a229487bc6644da9ccb7e427dd8cc60cb8a62/pluggy-0.13.1-py2.py3-none-any.whl
Collecting more-itertools>=4.0.0 (from pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/72/96/4297306cc270eef1e3461da034a3bebe7c84eff052326b130824e98fc3fb/more_itertools-8.2.0-py3-none-any.whl (43kB)
    100% |████████████████████████████████| 51kB 1.8MB/s ta 0:00:011
[?25hCollecting py>=1.5.0 (from pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/99/8d/21e1767c009211a62a8e3067280bfce76e89c9f876180308515942304d2d/py-1.8.1-py2.py3-none-any.whl (83kB)
    100% |████████████████████████████████| 92kB 1.5MB/s ta 0:00:011
[?25hCollecting wcwidth (from pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/f6/d5/1ecdac957e3ea12c1b319fcdee8b6917ffaff8b4644d673c4d72d2f20b49/wcwidth-0.1.9-py2.py3-none-any.whl
Collecting importlib-metadata>=0.12; python_version < "3.8" (from pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/ad/e4/891bfcaf868ccabc619942f27940c77a8a4b45fd8367098955bb7e152fb1/importlib_metadata-1.6.0-py2.py3-none-any.whl
Collecting packaging (from pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/62/0a/34641d2bf5c917c96db0ded85ae4da25b6cd922d6b794648d4e7e07c88e5/packaging-20.3-py2.py3-none-any.whl
Collecting zipp>=0.5 (from importlib-metadata>=0.12; python_version < "3.8"->pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/b2/34/bfcb43cc0ba81f527bc4f40ef41ba2ff4080e047acb0586b56b3d017ace4/zipp-3.1.0-py3-none-any.whl
Collecting pyparsing>=2.0.2 (from packaging->pytest>=4.5.0->allure-pytest)
  Downloading http://pypi.doubanio.com/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl (67kB)
    100% |████████████████████████████████| 71kB 1.3MB/s ta 0:00:011
[?25hInstalling collected packages: attrs, six, zipp, importlib-metadata, pluggy, allure-python-commons, more-itertools, py, wcwidth, pyparsing, packaging, pytest, allure-pytest
Successfully installed allure-pytest-2.8.13 allure-python-commons-2.8.13 attrs-19.3.0 importlib-metadata-1.6.0 more-itertools-8.2.0 packaging-20.3 pluggy-0.13.1 py-1.8.1 pyparsing-2.4.7 pytest-5.4.1 six-1.14.0 wcwidth-0.1.9 zipp-3.1.0
  生成报告
  要使Allure能够在测试执行期间收集测试结果,只需添加 --alluredir 选项,并提供指向应存储结果的文件夹的路径
pytest -n auto --alluredir=allure
  要在测试完成后查看实际报告,需要使用Allure命令行来让测试结果生成报告
allure serve allure
  allure 报告结构
  Overview:总览
  Categories:类别,默认是分了failed和error,凡是执行结果是其中一个的都会被归到类里面,可以通过这里快捷查看哪些用例是failed和error的
  Suites:测试套件,就是所有用例的层级关系,可以根据package、module、类、方法来查找用例
  Graphs:测试结果图形化,包括用例执行结果的分布图,优先级,耗时等
  Timeline:可以看到测试用例精确的测试时序(执行顺序),包括执行时间
  Behaviors:行为驱动,根据epic、feature、story来分组测试用例(后面会讲到)
  Packages:这就是按照package、module来分组测试用例了
  allure特性
  environment
  可以理解成环境变量参数,没有什么实际作用,个人觉得只是为了让别人知道本次测试的运行环境参数而已,显示啥都是自己定的;注意!!默认是没有的
  如何添加enviroment:
  通过创建environment.properties或者environment.xml文件,并把文件存放到allure-results(这个目录是生成最后的html报告之前,生成依赖文件的目录)目录下,就是 --alluredir 后面跟的目录。
# enviroment.properties
Browser=Chrome
Browser.Version=81.0.4044.92
Stand=Production
ApiUrl=127.0.0.1/login
python.Version=3.7.2
  或
# enviroment.xml
<environment>
    <parameter>
        <key>Browser</key>
        <value>Chrome</value>
    </parameter>
    <parameter>
        <key>Browser.Version</key>
        <value>81.0.4044.92</value>
    </parameter>
    <parameter>
        <key>Stand</key>
        <value>Production</value>
    </parameter>
        <parameter>
        <key>ApiUrl</key>
        <value>127.0.0.1/login</value>
    </parameter>
        <parameter>
        <key>python.Version</key>
        <value>3.7.2</value>
    </parameter>
</environment>
  Categories
  直译:分类
  通俗理解:测试用例结果的分类
  有两类缺陷:
  Product defects 产品缺陷(测试结果:failed)
  Test defects 测试缺陷(测试结果:error/broken)
  我们是可以创建自定义缺陷分类的,将 categories.json 文件添加到allure-results目录即可(和上面environment.properties放同一个目录)
  参数含义:
  name:分类名称
  matchedStatuses:测试用例的运行状态,默认["failed", "broken", "passed", "skipped", "unknown"]
  messageRegex:测试用例运行的错误信息,默认是 .* ,是通过正则去匹配的哦!
  traceRegex:测试用例运行的错误堆栈信息,默认是 .* ,也是通过正则去匹配的哦!
# categories.json
[
  {
    "name": "Ignored tests", 
    "matchedStatuses": ["skipped"] 
  },
  {
    "name": "Infrastructure problems",
    "matchedStatuses": ["broken", "failed"],
    "messageRegex": ".*bye-bye.*" 
  },
  {
    "name": "Outdated tests",
    "matchedStatuses": ["broken"],
    "traceRegex": ".*FileNotFoundException.*" 
  },
  {
    "name": "Product defects",
    "matchedStatuses": ["failed"]
  },
  {
    "name": "Test defects",
    "matchedStatuses": ["broken"]
  }
]
  Flaky test
  用法:在类或者方法上直接加 @Flaky ;官方也说了:可以将整个测试类标记为Flaky
  含义:
  简单来说就是,不够稳定的测试用例集,有可能前阵子还运行成功,过阵子就运行失败,理解成“闪烁”
  标记成Flaky的好处就是:当用例失败的情况下,我们能获取足够详细的信息,毕竟有可能某些测试用例是非常重要的
  如果不标记为Flaky的话,可能就要禁用这些测试
  allure.step()
  allure除了支持pytest自带的特性之外(fixture、parametrize、xfail、skip),自己本身也有强大的特性可以在pytest中使用。
  @allure.step的作用
  allure报告最重要的一点是,它允许对每个测试用例进行非常详细的步骤说明。
  通过 @allure.step() 装饰器,可以让测试用例在allure报告中显示更详细的测试过程。
  注意点:
  step() 只有一个参数,就是title,你传什么,在allure上就显示什么。
  可以像python字符串一样,支持位置参数和关键字参数 {0},{arg2},可看第四步那里,如果函数的参数没有匹配成功就会报错哦。
  step() 的使用场景,给我感觉就是,当方法之间嵌套会比较有用,否则的话只会显示一个步骤,类似下面图。
"""要使Allure能够在测试执行期间收集测试结果,只需添加 --alluredir 选项,并提供指向应存储结果的文件夹的路径"""
!pytest allure/allure_step.py -n auto --alluredir=allure/allure_json
============================= test session starts ==============================
platform linux -- Python 3.6.9, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /home/ubuntu/MySpace/Python/pytest
plugins: allure-pytest-2.8.13, xdist-1.31.0, rerunfailures-9.0, html-2.1.1, assume-2.2.1, forked-1.1.3, metadata-1.8.0, repeat-0.8.0
gw0 [1][1m[1m
.                                                                        [100%]
============================== 1 passed in 0.64s ===============================
"""生成报告"""
!allure serve allure/allure_json/
  allure.attach
  作用:allure报告还支持显示许多不同类型的附件,可以补充测试结果;自己想输出啥就输出啥,挺好的。
  **======语法一=**
  语法: allure.attach(body, name, attachment_type, extension)
  参数列表:
  body:要显示的内容(附件)
  name:附件名字
  attachment_type:附件类型,是 allure.attachment_type 里面的其中一种
  extension:附件的扩展名(比较少用)
  allure.attachment_type提供了哪些附件类型?
    TEXT = ("text/plain", "txt")
    CSV = ("text/csv", "csv")
    TSV = ("text/tab-separated-values", "tsv")
    URI_LIST = ("text/uri-list", "uri")
    HTML = ("text/html", "html")
    
    XML = ("application/xml", "xml")
    JSON = ("application/json", "json")
    YAML = ("application/yaml", "yaml")
    PCAP = ("application/vnd.tcpdump.pcap", "pacp")
    PDF = ("application/pdf", "pdf")
    
    PNG = ("image/png", "png")
    JPG = ("image/jpg", "jpg")
    SVG = ("image/svg-xml", "svg")
    GIF = ("image/gif", "gif")
    BMP = ("image/bmp", "bmp")
    TIFF = ("image/tiff", "tiff")
    
    MP4 = ("image/mp4", "mp4")
    OGG = ("image/ogg", "ogg")
    WEBM = ("image/webm", "webm")
  ==语法二
  语法二: allure.attach.file(source, name, attachment_type, extension)
  参数列表:
  source:文件路径,相当于传一个文件
  name:附件名字
  attachment_type:附件类型,是 allure.attachment_type中的其中一种
  extension:附件的扩展名(比较少用)
import allure
import pytest


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

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

    request.addfinalizer(finalizer_module_scope_fixture)


def test_with_attacments_in_fixture_and_finalizer(attach_file_in_module_scope_fixture_with_finalizer):
    pass


def test_multiple_attachments():
    allure.attach('<head></head><body> 一个HTML页面 </body>', 'Attach with HTML type', allure.attachment_type.HTML)
    allure.attach.file('./reports.html', attachment_type=allure.attachment_type.HTML)
  allure.description
  作用:可以添加足够详细的测试用例描述,以便于管理层查看
  语法格式:
  @allure.description(str)
  在测试用例函数声明下方添加""" """
  @allure.description_html(str):相当于传一个HTML代码组成的字符串,类似allure.attach()中传HTML
import allure

# 方式一
@allure.description("""
这是一个@allure.description装饰器
没有特别的用处
""")
def test_description_from_decorator():
    assert 42 == int(6 * 7)

# 方式二
def test_unicode_in_docstring_description():
    """
    当然,在方法声明的下一行这样子写,也算一种添加description的方式哦
    """
    assert 42 == int(6 * 7)

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

"""收集测试数据及测试范围"""
!pytest allure/allure_description.py
============================= test session starts ==============================
platform linux -- Python 3.6.9, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /home/ubuntu/MySpace/Python/pytest
plugins: allure-pytest-2.8.13, xdist-1.31.0, rerunfailures-9.0, html-2.1.1, assume-2.2.1, forked-1.1.3, metadata-1.8.0, repeat-0.8.0
collected 3 items                                                              

allure/allure_description.py ...                                         [100%]

============================== 3 passed in 0.02s ===============================
!allure serve allure/
Generating report to temp directory...
Report successfully generated to /tmp/2532045504637552864/allure-report
Starting web server...
2020-04-26 10:37:47.823:INFO::main: Logging initialized @5243ms to org.eclipse.jetty.util.log.StdErrLog
Can not open browser because this capability is not supported on your platform. You can use the link below to open the report manually.
Server started at <http://127.0.0.1:33287/>. Press <Ctrl+C> to exit
  allure.title
  作用:
  使得测试用例的标题更具有可读性,毕竟我们可以写成中文
  支持占位符传递关键字参数哦
  如果没有添加 @allure.title() 的话,测试用例的标题默认就是函数名,这样的可读性不高,毕竟咱们是中国人,显示中文title还是很有必要的
import pytest, allure


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


@allure.title("成功登录,测试数据是:{test_loginss}")
@pytest.mark.parametrize("test_loginss", [
    {"username": "name1", "pwd": "pwd1"},
    {"username": "name2", "pwd": "pwd2"}], indirect=True)
def test_success_login(test_loginss):
    name, pwd = test_loginss
    allure.attach(f"账号{name},密码{pwd}")
    
@allure.title("多个参数{name},{phone},{age}")
@pytest.mark.parametrize("name,phone,age", [
    (1, 2, 3),
    (4, 5, 6),
    (7, 8, 9)
])
def test_test_test(name, phone, age):
    print(name, phone, age)
"""收集测试范围与测试数据"""
!pytest allure/allure_title.py
"""生成测试报告"""
!allure server allure/allure_json
  allure链接
  先看 3 个装饰器
def link(url, link_type=LinkType.LINK, name=None):
    return safely(plugin_manager.hook.decorate_as_link(url=url, link_type=link_type, name=name))


def issue(url, name=None):
    return link(url, link_type=LinkType.ISSUE, name=name)


def testcase(url, name=None):
    return link(url, link_type=LinkType.TEST_CASE, name=name)
  三个装饰器的区别:
  issue()和testcase()其实调用的也是link(),只是link_type不一样
  必传参数 url:跳转的链接
  可选参数 name:显示在allure报告的名字,如果不传就是显示完整的链接;建议传!!不然可读性不高
  可以理解成:三个方法是一样的,我们都提供跳转链接和名字,只是链接的type不一样,最终显示出来的样式不一样而已【type不一样,样式不一样】
  如果你喜欢,只用@allure.link()也可以
  而出现三个装饰器的原因是为了更好地将链接分类【访问连接、Bug链接、测试用例链接】
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='点击我看一看youtube吧')
def test_with_named_link():
    pass


@allure.issue('140', 'bug issue链接')
def test_with_issue_link():
    pass


@allure.testcase(TEST_CASE_LINK, '测试用例地址')
def test_with_testcase_link():
    pass

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号