Allure 是一个灵活且可扩展的测试报告工具,可以与多个测试框架集成,如 JUnit, TestNG, pytest, Cucumber 等,并支持多种语言环境。它会生成详细的测试报告,帮助团队快速定位失败的测试用例,评估测试覆盖率,以及跟踪测试进度。
Allure 报告的主要特点包括:
- 丰富的图表:提供测试结果的概览,如通过率、失败率等。
- 详细的时间轴:显示每个测试用例的执行时间和状态。
- 步骤详情:展示测试用例中的每一个步骤,便于追踪问题。
- 附件支持:可以附加屏幕截图、日志文件等,有助于问题复现。
- 标签和分类:通过标签对测试用例进行分类,方便筛选和查询。
部署 Allure
下载 Allure :
访问 Allure 下载最新包(allure-2.xx.x.zip),解压并重命名 allure 后粘贴至项目根目录下。结构如下:
Project/
│
├── allure/
│ ├── bin/
│ ├── config/
│ ├── lib/
│ └── plugins/
│
├── Config/
│ └── pytest.ini # 自定义 mark 标记
│
├── Data/
│ └── parametrize.json # 根据策略模块
│
├── Package/ # 程序目录
│ ├── __init__.py # 包初始化文件,可以定义一些变量或执行一些操作。当然里面什么都不写也可以。
│ ├── fixture_fun.py # 定义Fixture,比如初始化数据、清理数据等操作
│ ├── module1.py # 应用程序模块,比如连接数据库操作数据,接口请求等操作,推荐按功能封装成类
│ └── module2.py # 应用程序模块,比如连接数据库操作数据,接口请求等操作,推荐按功能封装成类
│
├── Test/ # 测试用例目录
│ ├── __init__.py # 包初始化文件
│ ├── test_module1.py # 测试 module1 的测试用例
│ └── test_module2.py # 测试 module2 的测试用例
├── Tools/ # 工具目录
│ ├── __init__.py # 包初始化文件
│ └── files_processor.py # 文件处理工具
├── app.py # 项目启动文件
├── requirements.txt # 项目依赖项列表
└── README.md # 项目说明文档
安装 allure-pytest :
pip install allure-pytest
编辑 app.py ,支持运行 allure 可执行文件:
# app.py
import pytest
import sys
import logging
import argparse
import os
import subprocess
# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def run_tests(test_target, mark):
if mark is None:
# "-c", "Config/pytest.ini" 指定 pytest.ini 的路径
# "--alluredir=./result" 指定 allure 生成的结果文件保存至根目录下result目录中
# "--clean-alluredir" 运行前清除 ./result
pytest_args = ["-c", "Config/pytest.ini", "-v", "--clean-alluredir", "--alluredir=./result", test_target]
else:
# "-m", mark 指定标记
pytest_args = ["-c", "Config/pytest.ini", "-v", "--clean-alluredir", "--alluredir=./result", test_target, "-m", mark]
try:
# 运行测试
code = pytest.main(pytest_args)
# 根据退出码判断测试是否成功
exit_messages = {
0: "全部测试用例通过",
1: "部分测试用例未通过",
2: "测试过程中有中断或其他非正常终止。",
3: "内部错误",
4: "pytest遇到了命令行解析错误",
5: "pytest无法找到任何测试用例"
}
logging.info(exit_messages.get(code, "未知的退出码"))
except Exception as e:
logging.error(f"运行测试时发生错误: {e}")
return 1
return code
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="使用指定的命令运行 pytest 测试。")
parser.add_argument('test_target', nargs='?', type=str, default="Test/", help='指定运行命令。 (默认: Test/)')
# 命令行新增参数-mark,可选参数
parser.add_argument('-m', '--mark', nargs='?', type=str, help='指定运行命令。 (默认: Test/)')
args = parser.parse_args()
exit_code = run_tests(args.test_target, args.mark)
# 生成 Allure 报告
try:
allure_command = [
r".\allure\bin\allure.bat", "generate",
"./result",
"-o", "./report",
"--clean"
]
result = subprocess.run(allure_command, check=True, text=True, capture_output=True,cwd=os.getcwd())
logging.info("Allure 报告生成成功")
logging.info(result.stdout)
except subprocess.CalledProcessError as e:
logging.error(f"生成 Allure 报告时出错: {e}")
logging.error(e.stderr)
sys.exit(exit_code)
使用 allure
allure 支持自定义设置,包括:
-
@allure.epic():用于标记测软件系统名称,例如:XX管理系统。
-
@allure.feature():用于标记被测功能模块,例如:用户管理模块。
-
@allure.story():用于标记被测功能点或场景,例如:删除用户。
-
@allure.title():用于标记测试用例的标题,例如:冒烟测试-删除用户。
-
@allure.description():用于为测试用例添加描述信息,例如:验证是否可以删除用户。
-
@allure.tag():用于给测试用例添加标签。这些标签可以用来分类测试用例,便于在生成的测试报告中进行筛选和组织。例如:冒烟测试。
-
@allure.severity():用于指定测试用例的重要性级别,由高到低分为 blocker、critical、normal、minor、trivial 五级。
-
@pytest.allure.step():用于标记测试步骤。
假设书籍管理系统有用户管理模块,系统管理员登录系统后可以新增、编辑、删除用户。使用 pytest + allure 构建测试:
Package 目录下新建 user.py ,编写需要用到的函数。比如登录、获取用户列表、删除用户和查询数据库用户数据:
import allure
@allure.step("登录获取token")
def get_token(user_name, password):
if user_name == "JZY" and password == "123456":
# 此处省略登录的代码,直接返回token
return True, "token"
return False, "具体的错误原因"
@allure.step("获取用户列表")
def get_user_list(token):
if token != "token":
return False, "用户未登录"
# 此处省略获取用户列表的代码,直接返回用户列表,应该有异常处理,比如请求地址错误等
return True, [{"username": "test_user", "user_id":1},{"username": "test_user1", "user_id":2}]
@allure.step("删除用户")
def delete_user(token, user_id):
if token != "token" or not user_id:
return False, "token错误"
# 此处省略删除用户的代码,直接返回删除结果
return True, "删除成功"
@allure.step("查询数据库中用户数据")
def select_user():
# 此处省略查询数据库中用户数据的代码,直接返回查询结果
return True, [{"username": "test_user1", "user_id":2}]
Test 目录下新建 test_user.py ,编写测试用例:
import allure
from Package.user import get_token, get_user_list, delete_user
@allure.epic("书籍管理平台接口测试")
@allure.feature("用户管理模块测试")
class TestUserManagement:
@allure.story("新增用户测试")
@allure.title("新增用户-冒烟")
@allure.description("验证系统可以新增用户")
@allure.severity("blocker")
def test_add_user_smoke(self):
pass
@allure.story("新增用户测试")
@allure.title("新增用户-正向测试")
@allure.description("验证系统可以正确新增符合条件的用户")
@allure.severity("critical")
def test_add_user_success(self):
pass
@allure.story("新增用户测试")
@allure.title("新增用户-异向测试")
@allure.description("验证系统可以正确处理新增用户的异常参数,包括sql注入、边界值等")
@allure.severity("critical")
def test_add_user_fail(self):
pass
@allure.story("删除用户测试")
@allure.title("删除用户-冒烟")
@allure.description("验证系统可以删除用户")
@allure.severity("blocker")
def test_delete_user_smoke(self):
result, user_token = get_token("JZY", "123456")
if not result:
assert False, "用户登录失败,速检查原因"
result, user_list = get_user_list(user_token)
if not result:
assert False, user_list
result, msg = delete_user(user_token, user_list[0]["user_id"])
assert result, msg
python .\app.py ,运行结果:
result 目录下是产生的测试数据,report 目录下的 index.html 是我们最终的目标。在浏览器打开 index.html :
allure 使用参数化数据
除了使用装饰器自定义设置外,allure 还可以使用测试用例的参数动态设置。通过 allure.dynamic.特性 设置:
import allure
import pytest
# 定义测试数据
test_data = [
("登录账号 - 正确密码", "admin", "123456"),
("登录账号 - 错误密码", "admin", "wrongpassword"),
("登录账号 - 错误账号", "adminerror", "123456"),
("登录账号 - 空密码", "admin", "")
]
# 参数化测试
@pytest.mark.parametrize("title, user_name, password", test_data, ids=[data[0] for data in test_data])
@allure.story("测试参数化")
@allure.severity("blocker")
def test_login(title, user_name, password):
# 动态设置测试用例标题
allure.dynamic.title(title)
# 动态设置测试用例描述
allure.dynamic.description(f"用户名: {user_name}, 密码: {password}")
# 模拟登录操作
with allure.step("执行登录操作"):
# 打印的日志会被allure记录
print(f"尝试使用用户名 '{user_name}' 和密码 '{password}' 登录")
# 假设这是一个成功的登录
assert True, "登录失败"
python .\app.py ,运行结果:
所有特性的动态设置都可以所有测试用例的参数,包括下述的添加附件。
为测试结果添加附件
有两种方式添加附件:
allure.attach(body, name=None, attachment_type="text/plain", extension="attach")
allure.attach.file(source, name=None, attachment_type=None, extension=None)
allure.attach() 的参数中,要求 body 的值必须是 bytes或str 类型,name 为此附件的名称(可作附件说明),attachment_type 指定数据的类型(默认文本就行,添加文件附件推荐使用 allure.attach.file() ),extension 不必理会。
allure.attach.file() 的参数中,source 指定文件的路径,name 为此附件的名称(可作附件说明),attachment_type 指定数据的类型,extension 不必理会。
例子:
import allure
@allure.story("添加附件测试")
@allure.severity("blocker")
def test_text():
# 添加附件文本
allure.attach(
body="这是 test_login 的文本附件",
name="文本附件说明",
attachment_type=allure.attachment_type.TEXT
)
assert True, "登录失败"
@allure.story("添加附件测试")
@allure.severity("blocker")
def test_files():
# 添加附件文本
allure.attach.file(
source="Test/img.png", # app.py的相对路径
name="文件附件说明",
attachment_type=allure.attachment_type.PNG
)
assert True, "登录失败"
python .\app.py ,运行结果:
THEEND
© 转载需要保留原始链接,未经明确许可,禁止商业使用。CC BY-NC-ND 4.0
...