第十六:Allure-pytest功能特性介绍

第十六:Allure-pytest功能特性介绍,第1张

1.前言

1.1.Allure框架是一个灵活的轻量级多语言测试报告工具,它不仅以web的方式展示了简介的测试结果,而且允许参与开发过程的每个人从日常执行的测试中最大限度的提取有用信息。

1.2.从dev/qa的角度来看,Allure报告简化了常见缺陷的统计:失败的测试可以分为bug和被中断的测试,还可以配置日志、步骤、fixture、附件、计时、执行历史以及与TMS和BUG管理系统集成,所以,通过以上配置,所有负责的开发人员和测试人员可以尽可能的掌握测试信息。

1.3.从管理者的角度来看,Allure提供了一个清晰的“大图”,其中包括已覆盖的特性、缺陷聚集的位置、执行时间轴的外观以及许多其他方便的事情。allure的模块化和可扩展性保证了您总是能够对某些东西进行微调,使Allure更适合您,那么今天我们就来说说如何使报告更加详细的显示我们需要的信息,以及allure与jenkins的集成。

2.生成报告

2.1.pytest框架编写的项目如何生成测试报告,具体参考:pytest进阶之html测试报告。

https://blog.csdn.net/hyq413950612/article/details/123743418?spm=1001.2014.3001.5501

2.2.注意:python使用的allure插件为allure-pytest

3.测试代码

3.1.conftest.py

import pytest
import allure

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
    outcome = yield
    report = outcome.get_result()
    report.nodeid = report.nodeid.encode("utf-8").decode("unicode_escape")  # 解决乱码

@allure.step("打开浏览器")
def fixture_step():
    pass

@pytest.fixture
def init_url():
    fixture_step()
    yield True

3.2.test_allure_feature.py

import pytest
import allure
import os

def login(username=None, password=None):
    """模拟登录"""
    user = "linux超"
    pwd = "123456"
    if user == username and pwd == password:
        return {"code": 1001, "msg": "登录成功", "data": None}
    elif "" == password or password is None and username:
        return {"code": 1002, "msg": "密码不能为空", "data": None}
    elif "" == username or username is None and password:
        return {"code": 1003, "msg": "用户名不能为空", "data": None}
    else:
        return {"code": 1004, "msg": "用户名或密码错误", "data": None}

@allure.step("输入用户名")
def input_username(user):
    print("输入用户名")
    return user

@allure.step("输入密码")
def input_password(pwd):
    print("输入密码")
    return pwd

login_success_data = [
    # 测试数据
    {
        "case": "用户名正确, 密码正确",
        "user": "linux超",
        "pwd": "123456",
        "expected": {"code": 1001, "msg": "登录成功", "data": None}
    }
]

login_fail_data = [
    {
        "case": "用户名正确, 密码为空",
        "user": "linux超",
        "pwd": "",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    },
    {
        "case": "用户名为空, 密码正确",
        "user": "",
        "pwd": "linux超哥",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    },
    {
        "case": "用户名错误, 密码错误",
        "user": "linux",
        "pwd": "linux",
        "expected": {"code": 1004, "msg": "用户名或密码错误", "data": None}
    }
]

username_none = [
    {
        "case": "缺省用户名参数",
        "pwd": "123456",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    }
]
password_none = [
    {
        "case": "缺省密码参数",
        "user": "linux超",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    }
]
# 改变输出结果
ids_login_success_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_success_data
]
ids_login_fail_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_fail_data
]
ids_username_none = [
    "测试{}密码{}期望值{}".
        format(data["case"], data["pwd"], data["expected"]) for data in username_none
]
ids_password_none = [
    "测试{}用户名:{}期望值{}".
        format(data["case"], data["user"], data["expected"]) for data in password_none
]

@allure.feature("登录模块")
class TestLogin(object):

    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("测试登录成功")
    @allure.title("登录成功场景-{data}")
    @pytest.mark.parametrize("data", login_success_data, ids=ids_login_success_data)
    def test_login_success(self, data):
        """测试登录成功"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.CRITICAL)
    @allure.story("测试登录失败")
    @pytest.mark.parametrize("data", login_fail_data, ids=ids_login_fail_data)
    def test_login_fail(self, data):
        """测试用户名或密码错误"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试用户名参数缺失")
    @pytest.mark.parametrize("data", username_none, ids=ids_username_none)
    def test_username_none(self, data):
        """测试缺省用户名"""
        pwd = input_password(data["pwd"])
        result = login(password=pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试密码参数缺失")
    @pytest.mark.parametrize("data", password_none, ids=ids_password_none)
    def test_password_none(self, data):
        """测试缺省密码"""
        user = input_username(data["user"])
        result = login(username=user)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试初始化地址")
    @allure.testcase("https://www.cnblogs.com/linuxchao/", "测试用例地址")
    def test_init_url(self, init_url):
        flag = init_url
        assert flag is True

    @allure.severity(allure.severity_level.NORMAL)
    @allure.story("测试失败用例与用例中添加附件")
    @allure.link("https://www.cnblogs.com/linuxchao/", name="bug链接")
    @allure.description("这是一个一直执行失败的测试用例")
    def test_failed(self):
        """你也可以在这里添加用例的描述信息,但是会被allure.description覆盖"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试broken用例")
    @allure.issue("https://www.cnblogs.com/linuxchao/", "错误链接")
    def test_broken(self):
        """broken"""
        with open("broken.json", "r", encoding='utf8') as f:
            f.read()

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试无条件跳过测试用例")
    @pytest.mark.skip(reason="无条件跳过")
    def test_skip(self):
        """skip"""
        pass


if __name__ == '__main__':
    pytest.main(["-vsq",
                 "--alluredir", "./allure-results", ])
    os.system(r"allure generate --clean ./allure-results -o ./allure-report")

3.3.test_allure_fixture.py

import pytest
import os
import allure

def function_scope_step():
    print("function_scope_step")

def class_scope_step():
    print("class_scope_step")

def module_scope_step():
    print("module_scope_step")

def session_scope_step():
    print("session_scope_step")

def step_inside_test_body():
    print("step_inside_test_body")

@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)

@allure.severity(allure.severity_level.BLOCKER)
@allure.feature("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()


if __name__ == '__main__':
    pytest.main(["-vsq",
                 "--alluredir", "./allure-results", ])
    os.system(r"allure generate --clean ./allure-results -o ./allure-report")

3.4.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"]
  }
]

3.5.environment.properties

Browser=Chrome
Browser.Version=63.0
Stand=Production
ApiUrl=127.0.0.1/login
python.Version=3.6

3.6.run.py

import pytest
import os

if __name__ == '__main__':
    pytest.main(["-sq",
                 "--alluredir", "./allure-results"])
    os.system(r"allure generate --clean allure-results -o allure-report")

4.目录结构

5.Allure特性:

***5.1.Environment:***在Allure报告中添加环境信息,通过创建environment.properties或者environment.xml文件,并把文件存放到allure-results(这个目录是生成最后的html报告之前,生成依赖文件的目录)目录下。

5.2.environment.properties

Browser=Chrome
Browser.Version=63.0
Stand=Production
ApiUrl=127.0.0.1/login
python.Version=3.6

或者
5.3.environment.xml

<environment>
    <parameter>
        <key>Browserkey>
        <value>Chromevalue>
    parameter>
    <parameter>
        <key>Browser.Versionkey>
        <value>63.0value>
    parameter>
    <parameter>
        <key>Standkey>
        <value>Productionvalue>
    parameter>
        <parameter>
        <key>ApiUrlkey>
        <value>127.0.0.1/loginvalue>
    parameter>
        <parameter>
        <key>python.Versionkey>
        <value>3.6value>
    parameter>
environment>

5.4.执行run.py查看报告。

***6.Categories:***测试报告默认统计两种类型的测试用例结果,失败的用例和故障测试用例,我们可以自定义添加用例的统计类型,同样需要在allure-results目录下新建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"]
  }
]

6.1.执行run.py查看报告。

***7.Fixtures and Finalizers:***Fixtures和Finalizers是pytest在测试开始和测试结束调用的方法,allure会自动跟踪每一个fixture的调用,并且详细显示会调用哪些fixture和参数,而且会保留正确的调用顺数。

7.1.test_allure_fixture.py

import pytest
import os
import allure

def function_scope_step():
    print("function_scope_step")

def class_scope_step():
    print("class_scope_step")

def module_scope_step():
    print("module_scope_step")

def session_scope_step():
    print("session_scope_step")

def step_inside_test_body():
    print("step_inside_test_body")

@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)

@allure.severity(allure.severity_level.BLOCKER)
@allure.feature("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()


if __name__ == '__main__':
    pytest.main(["-vsq",
                 "--alluredir", "./allure-results", ])
    os.system(r"allure generate --clean ./allure-results -o ./allure-report")

7.2.执行run.py查看报告。

一.Allure常用注解
feature::标注主要功能模块
story:标注feature功能模块下的分支功能
severity:标注测试用例的重要级别
step:标注测试用例的重要步骤
Issue和TestCase:标注Issue、Case,可加入URL

[email protected][email protected]:feature和story被称为行为驱动标记,因为使用这个两个标记,通过报告可以更加清楚的掌握每个测试用例的功能和每个测试用例的测试场景。***

2.1.在test_allure_feature.py文件中的测试类使用@allure.feature修饰, 测试方法使用@allure.story修饰。

import pytest
import allure
import os

def login(username=None, password=None):
    """ 模拟登录 """
    user = "linux超"
    pwd = "123456"
    if user == username and pwd == password:
        return {"code": 1001, "msg": "登录成功", "data": None}
    elif "" == password or password is None and username:
        return {"code": 1002, "msg": "密码不能为空", "data": None}
    elif "" == username or username is None and password:
        return {"code": 1003, "msg": "用户名不能为空", "data": None}
    else:
        return {"code": 1004, "msg": "用户名或密码错误", "data": None}

@allure.step("输入用户名")
def input_username(user):
    print("输入用户名")
    return user

@allure.step("输入密码")
def input_password(pwd):
    print("输入密码")
    return pwd

login_success_data = [
    # 测试数据
    {
        "case": "用户名正确, 密码正确",
        "user": "linux超",
        "pwd": "123456",
        "expected": {"code": 1001, "msg": "登录成功", "data": None}
    }
]

login_fail_data = [
    {
        "case": "用户名正确, 密码为空",
        "user": "linux超",
        "pwd": "",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    },
    {
        "case": "用户名为空, 密码正确",
        "user": "",
        "pwd": "linux超哥",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    },
    {
        "case": "用户名错误, 密码错误",
        "user": "linux",
        "pwd": "linux",
        "expected": {"code": 1004, "msg": "用户名或密码错误", "data": None}
    }
]

username_none = [
    {
        "case": "缺省用户名参数",
        "pwd": "123456",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    }
]
password_none = [
    {
        "case": "缺省密码参数",
        "user": "linux超",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    }
]

# 改变输出结果
ids_login_success_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_success_data
]
ids_login_fail_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_fail_data
]
ids_username_none = [
    "测试{}密码{}期望值{}".
        format(data["case"], data["pwd"], data["expected"]) for data in username_none
]
ids_password_none = [
    "测试{}用户名:{}期望值{}".
        format(data["case"], data["user"], data["expected"]) for data in password_none
]

@allure.feature("登录模块")
class TestLogin(object):

    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("测试登录成功")
    @allure.title("登录成功场景-{data}")
    @pytest.mark.parametrize("data", login_success_data, ids=ids_login_success_data)
    def test_login_success(self, data):
        """测试登录成功"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.CRITICAL)
    @allure.story("测试登录失败")
    @pytest.mark.parametrize("data", login_fail_data, ids=ids_login_fail_data)
    def test_login_fail(self, data):
        """测试用户名或密码错误"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试用户名参数缺失")
    @pytest.mark.parametrize("data", username_none, ids=ids_username_none)
    def test_username_none(self, data):
        """测试缺省用户名"""
        pwd = input_password(data["pwd"])
        result = login(password=pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试密码参数缺失")
    @pytest.mark.parametrize("data", password_none, ids=ids_password_none)
    def test_password_none(self, data):
        """测试缺省密码"""
        user = input_username(data["user"])
        result = login(username=user)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试初始化地址")
    @allure.testcase("https://www.cnblogs.com/linuxchao/", "测试用例地址")
    def test_init_url(self, init_url):
        flag = init_url
        assert flag is True

    @allure.severity(allure.severity_level.NORMAL)
    @allure.story("测试失败用例与用例中添加附件")
    @allure.link("https://www.cnblogs.com/linuxchao/", name="bug链接")
    @allure.description("这是一个一直执行失败的测试用例")
    def test_failed(self):
        """你也可以在这里添加用例的描述信息,但是会被allure.description覆盖"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试broken用例")
    @allure.issue("https://www.cnblogs.com/linuxchao/", "错误链接")
    def test_broken(self):
        """broken"""
        with open("broken.json", "r", encoding='utf8') as f:
            f.read()

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试无条件跳过测试用例")
    @pytest.mark.skip(reason="无条件跳过")
    def test_skip(self):
        """skip"""
        pass

if __name__ == '__main__':
    pytest.main(["-vsq",
                 "--alluredir", "./allure-results", ])
    os.system(r"allure generate --clean ./allure-results -o ./allure-report")

2.2.执行run.py查看报告。

2.3.以上两种标记不仅仅能够在测试报告中显示,而且还可以使用命令执行指定的测试模块或者场景。

[email protected]:此标记用来标识测试用例或者测试类的级别,分为blocker,critical,normal,minor,trivial5个级别,下面们把测试用例按级别标记,并查看一下测试报告。

import pytest
import allure
import os

def login(username=None, password=None):
    """ 模拟登录 """
    user = "linux超"
    pwd = "123456"
    if user == username and pwd == password:
        return {"code": 1001, "msg": "登录成功", "data": None}
    elif "" == password or password is None and username:
        return {"code": 1002, "msg": "密码不能为空", "data": None}
    elif "" == username or username is None and password:
        return {"code": 1003, "msg": "用户名不能为空", "data": None}
    else:
        return {"code": 1004, "msg": "用户名或密码错误", "data": None}

@allure.step("输入用户名")
def input_username(user):
    print("输入用户名")
    return user

@allure.step("输入密码")
def input_password(pwd):
    print("输入密码")
    return pwd

login_success_data = [
    # 测试数据
    {
        "case": "用户名正确, 密码正确",
        "user": "linux超",
        "pwd": "123456",
        "expected": {"code": 1001, "msg": "登录成功", "data": None}
    }
]

login_fail_data = [
    {
        "case": "用户名正确, 密码为空",
        "user": "linux超",
        "pwd": "",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    },
    {
        "case": "用户名为空, 密码正确",
        "user": "",
        "pwd": "linux超哥",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    },
    {
        "case": "用户名错误, 密码错误",
        "user": "linux",
        "pwd": "linux",
        "expected": {"code": 1004, "msg": "用户名或密码错误", "data": None}
    }
]

username_none = [
    {
        "case": "缺省用户名参数",
        "pwd": "123456",
        "expected": {"code": 1003, "msg": "用户名不能为空", "data": None}
    }
]
password_none = [
    {
        "case": "缺省密码参数",
        "user": "linux超",
        "expected": {"code": 1002, "msg": "密码不能为空", "data": None}
    }
]

# 改变输出结果
ids_login_success_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_success_data
]
ids_login_fail_data = [
    "测试{}用户名:{}密码{}期望值{}".
        format(data["case"], data["user"], data["pwd"], data["expected"]) for data in login_fail_data
]
ids_username_none = [
    "测试{}密码{}期望值{}".
        format(data["case"], data["pwd"], data["expected"]) for data in username_none
]
ids_password_none = [
    "测试{}用户名:{}期望值{}".
        format(data["case"], data["user"], data["expected"]) for data in password_none
]

@allure.feature("登录模块")
class TestLogin(object):

    @allure.severity(allure.severity_level.BLOCKER)
    @allure.story("测试登录成功")
    @allure.title("登录成功场景-{data}")
    @pytest.mark.parametrize("data", login_success_data, ids=ids_login_success_data)
    def test_login_success(self, data):
        """测试登录成功"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.CRITICAL)
    @allure.story("测试登录失败")
    @pytest.mark.parametrize("data", login_fail_data, ids=ids_login_fail_data)
    def test_login_fail(self, data):
        """测试用户名或密码错误"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试用户名参数缺失")
    @pytest.mark.parametrize("data", username_none, ids=ids_username_none)
    def test_username_none(self, data):
        """测试缺省用户名"""
        pwd = input_password(data["pwd"])
        result = login(password=pwd)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试密码参数缺失")
    @pytest.mark.parametrize("data", password_none, ids=ids_password_none)
    def test_password_none(self, data):
        """测试缺省密码"""
        user = input_username(data["user"])
        result = login(username=user)
        assert result == data["expected"]

    @allure.severity(allure.severity_level.MINOR)
    @allure.story("测试初始化地址")
    @allure.testcase("https://www.cnblogs.com/linuxchao/", "测试用例地址")
    def test_init_url(self, init_url):
        flag = init_url
        assert flag is True

    @allure.severity(allure.severity_level.NORMAL)
    @allure.story("测试失败用例与用例中添加附件")
    @allure.link("https://www.cnblogs.com/linuxchao/", name="bug链接")
    @allure.description("这是一个一直执行失败的测试用例")
    def test_failed(self):
        """你也可以在这里添加用例的描述信息,但是会被allure.description覆盖"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试broken用例")
    @allure.issue("https://www.cnblogs.com/linuxchao/", "错误链接")
    def test_broken(self):
        """broken"""
        with open("broken.json", "r", encoding='utf8') as f:
            f.read()

    @allure.severity(allure.severity_level.TRIVIAL)
    @allure.story("测试无条件跳过测试用例")
    @pytest.mark.skip(reason="无条件跳过")
    def test_skip(self):
        """skip"""
        pass


if __name__ == '__main__':
    pytest.main(["-vsq",
                 "--alluredir", "./allure-results", ])
    os.system(r"allure generate --clean ./allure-results -o ./allure-report")

[email protected]:pytest支持使用@allure.step修饰某些测试用例中需要的函数,使测试用例在allure报告中能够更加详细的显示测试过程。

4.1.test_allure_feature.py

@allure.step("输入用户名")  
def input_username():
    print("输入用户名")

@allure.step("输入密码")
def input_password():
    print("输入密码")

4.2.执行run.py查看报告。

4.3.conftest.py文件:@allure.step修饰的测试步骤还支持在conftest.py文件中定义,作为fixture的步骤,现在在项目目录下新建conftest.py文件。

4.4.conftest.py

@allure.step("打开浏览器")
def fixture_step():
    pass

@pytest.fixture
def init_url():
    fixture_step()
    yield True

4.5.test_allure_feature.py

def test_init_url(self, init_url):
        flag = init_url
        assert flag == True

4.6.执行run.py查看报告。

5.用例标题和用例描述定制详解

test_allure_title_describe.py

import allure
import pytest

@allure.feature('test_module_01')
@allure.story('test_story_01')
#test_case_01为用例title
def test_case_01():
    """
    用例描述:这是用例描述,Test case 01,描述本人
    """
    #注释为用例描述
    assert 0

if __name__ == '__main__':
    pytest.main(['-s', '-q', '--alluredir', './report'])

5.1.添加用例标题和用例描述,Report展示见下图。

[email protected]:如果想在报告中展示测试用例的描述信息,那么可以使用@allure.description(string)或者@allure.description_html(html代码)修饰你的测试用例(和第五点一样,但是第五点使用后会被allure.description覆盖)。

6.1.test_allure_feature.py

@allure.description("这是一个一直执行失败的测试用例")
    def test_failed(self):
        """你也可以在这里添加用例的描述信息,但是会被allure.description覆盖"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e

6.2.执行run.py查看报告。

[email protected]:使用allure.title(title)可以重命名测试用例在allure报告中的名称(和第五点一样,但是第五点使用后会被allure.title重新命名覆盖)。

7.1.test_allure_feature.py

@allure.title("登录成功场景-{data}")
    @pytest.mark.parametrize("data", login_success_data, ids=ids_login_success_data)
    def test_login_success(self, data):
        """测试登录成功"""
        user = input_username(data["user"])
        pwd = input_password(data["pwd"])
        result = login(user, pwd)
        assert result == data["expected"]

[email protected][email protected][email protected]
这三种特性都可以给测试用例添加一个链接。

10.1.test_allure_feature.py

@allure.testcase("https://www.cnblogs.com/linuxchao/", "测试用例地址")
    def test_init_url(self, init_url):
        flag = init_url
        assert flag == True
    @allure.link("https://www.cnblogs.com/linuxchao/", name="bug链接")
    @allure.description("这是一个一直执行失败的测试用例")
    def test_failed(self):
        """你也可以在这里添加用例的描述信息,但是会被allure.description覆盖"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e
    @allure.issue("https://www.cnblogs.com/linuxchao/", "错误链接")
    def test_broken(self):
        """broken"""
        with open("broken.json", "r", encoding='utf8') as f:
            f.read()

10.2.执行run.py查看报告。


11.allure.attach:使用allure.attach可以给报告中添加文件,图片,log,html代码等等。 修改test_allure_feature.py中如下用例, 并在用例所在目录添加attach.png图片。

def test_failed(self):
        """failed"""
        try:
            assert False
        except AssertionError as e:
            with open("attach.png", "rb") as f:
                context = f.read()
                allure.attach(context, "错误图片", attachment_type=allure.attachment_type.PNG)
            raise e

11.1.执行run.py查看报告。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/874541.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存