Pytest 插件 Allure 生成企业级测试报告详解
1. 什么是 Allure
1.1 Allure 简介
Allure 是一个轻量级、灵活的测试报告框架,专门用于生成美观、详细的企业级测试报告。它最初是为 Java 测试框架设计的,但现在也完美支持 Python 的 pytest 框架。
1.2 为什么需要 Allure
在日常测试工作中,我们经常会遇到以下问题:
- 测试报告不够直观:pytest 默认的报告只是简单的文本输出,不够美观
- 信息不够详细:无法清楚地看到测试步骤、截图、日志等详细信息
- 历史记录缺失:无法查看测试历史趋势和对比
- 团队协作不便:无法方便地分享和展示测试结果给团队成员和领导
- 问题定位困难:当测试失败时,难以快速定位问题原因
没有 Allure 的情况:
# 运行测试
pytest test_example.py -v
# 输出结果
======================== test session starts ==========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 3 items
test_example.py::test_login PASSED [ 33%]
test_example.py::test_create_user PASSED [ 66%]
test_example.py::test_delete_user FAILED [100%]
======================== FAILURES ==========================
test_delete_user FAILED
AssertionError: assert False
问题:
- 报告不够美观,只是简单的文本
- 无法看到详细的测试步骤
- 无法附加截图、日志等附件
- 无法查看历史趋势
- 不适合向领导汇报
使用 Allure 后:
# 运行测试并生成 Allure 报告
pytest test_example.py --alluredir=./allure-results
allure serve ./allure-results
# 生成一个美观的 HTML 报告,包含:
# - 详细的测试步骤
# - 测试截图
# - 测试日志
# - 历史趋势图
# - 测试分类和标签
# - 环境信息
优势:
- 美观的 HTML 报告,适合向领导汇报
- 详细的测试步骤,方便定位问题
- 支持截图、日志等附件
- 历史趋势分析
- 测试分类和标签管理
- 团队协作友好
1.3 Allure 的主要特点
- 美观的界面:现代化的 Web 界面,支持多种图表和可视化
- 详细的步骤:可以记录测试的每个步骤,方便问题定位
- 丰富的附件:支持截图、日志、文件等多种附件
- 历史追踪:可以查看测试历史趋势和对比
- 分类管理:支持测试分类、标签、优先级等管理
- 环境信息:可以记录测试环境信息
- 多语言支持:支持多种编程语言和测试框架
1.4 Allure 报告的核心概念
在深入学习 Allure 之前,我们需要了解几个核心概念:
- Test Case(测试用例):一个独立的测试函数
- Test Step(测试步骤):测试用例中的具体操作步骤
- Attachment(附件):测试过程中附加的截图、日志等文件
- Label(标签):用于分类和标记测试用例
- Suite(套件):测试用例的集合
- History(历史):测试执行的历史记录
2. 安装 Allure
2.1 安装 pytest-allure-adaptor 或 allure-pytest
Allure 在 Python 中有两个主要的适配器:
- allure-pytest(推荐):官方维护,功能更全面
- pytest-allure-adaptor:旧版本,不推荐使用
安装 allure-pytest:
pip install allure-pytest
指定版本安装:
# 安装特定版本
pip install allure-pytest==2.13.2
# 安装最新版本
pip install allure-pytest --upgrade
2.2 安装 Allure 命令行工具
Allure 报告需要 Allure 命令行工具来生成。安装方法因操作系统而异:
2.2.1 Windows 安装
方法 1:使用 Scoop 安装(推荐)
# 先安装 Scoop(如果没有)
# 在 PowerShell 中执行
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
# 使用 Scoop 安装 Allure
scoop install allure
方法 2:手动安装
# 1. 下载 Allure
# 访问 https://github.com/allure-framework/allure2/releases
# 下载 allure-2.13.2.zip(或最新版本)
# 2. 解压到某个目录,例如 C:allure
# 3. 将 C:allurebin 添加到系统环境变量 PATH 中
# 4. 验证安装
allure --version
2.2.2 macOS 安装
使用 Homebrew 安装:
brew install allure
2.2.3 Linux 安装
Ubuntu/Debian:
# 添加仓库
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update
# 安装
sudo apt-get install allure
或者使用 Snap:
sudo snap install allure --classic
2.3 验证安装
验证 Python 包安装:
pip show allure-pytest
输出示例:
Name: allure-pytest
Version: 2.13.2
Summary: Allure pytest integration
Location: /path/to/site-packages
验证 Allure 命令行工具:
allure --version
输出示例:
2.13.2
查看 Allure 帮助:
allure --help
3. Allure 基本使用
3.1 最简单的示例
让我们从一个最简单的例子开始:
创建测试文件 test_simple.py:
import pytest
import allure
def test_add():
"""测试加法"""
assert 1 + 1 == 2
def test_subtract():
"""测试减法"""
assert 5 - 3 == 2
运行测试并生成 Allure 报告:
# 1. 运行测试,生成 Allure 结果数据
pytest test_simple.py --alluredir=./allure-results
# 2. 生成并打开报告
allure serve ./allure-results
说明:
--alluredir=./allure-results:指定 Allure 结果数据的保存目录allure serve ./allure-results:生成临时报告并在浏览器中打开
3.2 查看报告
执行 allure serve ./allure-results 后,会自动:
- 生成 HTML 报告
- 启动本地服务器
- 在默认浏览器中打开报告
报告界面包含:
- Overview(概览):测试执行的整体情况
- Suites(套件):按测试套件查看
- Graphs(图表):测试结果的可视化图表
- Behaviors(行为):按行为分类查看
- Packages(包):按包/模块查看
3.3 生成静态报告
除了使用 allure serve 查看临时报告,还可以生成静态 HTML 报告:
# 生成静态报告
allure generate ./allure-results -o ./allure-report --clean
# 查看报告(需要手动打开)
# Windows: 在文件管理器中打开 allure-report/index.html
# macOS: open allure-report/index.html
# Linux: xdg-open allure-report/index.html
参数说明:
-o ./allure-report:指定报告输出目录--clean:清理输出目录(如果已存在)
4. Allure 装饰器详解
4.1 @allure.title – 设置测试标题
默认情况下,Allure 使用函数名作为测试标题。使用 @allure.title 可以自定义更友好的标题。
示例 1:基本用法
import allure
import pytest
@allure.title("用户登录测试")
def test_login():
"""测试用户登录功能"""
assert True
@allure.title("创建新用户")
def test_create_user():
"""测试创建用户功能"""
assert True
示例 2:动态标题
import allure
import pytest
@pytest.mark.parametrize("username", ["admin", "user", "guest"])
@allure.title("测试用户 {username} 的登录功能")
def test_login_with_username(username):
"""使用参数化测试,标题中包含参数"""
assert username in ["admin", "user", "guest"]
示例 3:使用函数参数
import allure
@allure.title("测试用户 {user_id} 的信息")
def test_user_info(user_id):
"""标题中使用函数参数"""
assert user_id > 0
4.2 @allure.description – 添加测试描述
使用 @allure.description 可以为测试用例添加详细的描述信息。
示例 1:使用装饰器参数
import allure
@allure.description("""
这是一个详细的测试描述:
1. 测试用户登录功能
2. 验证用户名和密码
3. 检查登录后的跳转
""")
def test_login():
assert True
示例 2:使用文档字符串
import allure
@allure.description
def test_login():
"""
测试用户登录功能
前置条件:
- 用户已注册
- 数据库连接正常
测试步骤:
1. 打开登录页面
2. 输入用户名和密码
3. 点击登录按钮
预期结果:
- 登录成功
- 跳转到首页
"""
assert True
示例 3:动态描述
import allure
def test_with_dynamic_description():
"""测试动态描述"""
allure.dynamic.description("这是动态添加的描述")
assert True
4.3 @allure.step – 定义测试步骤
@allure.step 是 Allure 中最重要的装饰器之一,用于定义测试步骤。步骤会在报告中详细显示,方便定位问题。
示例 1:基本用法
import allure
@allure.step("打开登录页面")
def open_login_page():
"""打开登录页面"""
print("正在打开登录页面...")
return True
@allure.step("输入用户名: {username}")
def input_username(username):
"""输入用户名"""
print(f"正在输入用户名: {username}")
return True
@allure.step("输入密码")
def input_password():
"""输入密码"""
print("正在输入密码...")
return True
@allure.step("点击登录按钮")
def click_login_button():
"""点击登录按钮"""
print("正在点击登录按钮...")
return True
def test_login():
"""测试登录流程"""
open_login_page()
input_username("admin")
input_password()
click_login_button()
assert True
示例 2:在测试函数中使用步骤
import allure
def test_login_with_steps():
"""测试登录流程(在测试函数中定义步骤)"""
with allure.step("打开登录页面"):
print("打开登录页面")
with allure.step("输入用户名和密码"):
username = "admin"
password = "123456"
print(f"输入用户名: {username}")
print(f"输入密码: {password}")
with allure.step("点击登录按钮"):
print("点击登录按钮")
with allure.step("验证登录结果"):
assert True
示例 3:步骤嵌套
import allure
@allure.step("准备测试数据")
def prepare_data():
"""准备测试数据"""
with allure.step("连接数据库"):
print("连接数据库")
with allure.step("查询用户信息"):
print("查询用户信息")
with allure.step("清理临时数据"):
print("清理临时数据")
def test_with_nested_steps():
"""测试嵌套步骤"""
prepare_data()
assert True
示例 4:步骤参数化
import allure
@allure.step("处理用户 {user_id}")
def process_user(user_id, action):
"""处理用户操作"""
print(f"处理用户 {user_id} 的 {action} 操作")
return True
def test_process_users():
"""测试处理多个用户"""
users = [1, 2, 3]
for user_id in users:
process_user(user_id, "登录")
assert True
4.4 @allure.severity – 设置测试优先级
使用 @allure.severity 可以标记测试用例的优先级。
优先级级别:
allure.severity_level.BLOCKER:阻塞级别(最高)allure.severity_level.CRITICAL:严重级别allure.severity_level.NORMAL:正常级别(默认)allure.severity_level.MINOR:次要级别allure.severity_level.TRIVIAL:轻微级别(最低)
示例:
import allure
import pytest
@allure.severity(allure.severity_level.BLOCKER)
def test_critical_login():
"""关键登录测试"""
assert True
@allure.severity(allure.severity_level.CRITICAL)
def test_important_feature():
"""重要功能测试"""
assert True
@allure.severity(allure.severity_level.NORMAL)
def test_normal_feature():
"""普通功能测试"""
assert True
@allure.severity(allure.severity_level.MINOR)
def test_minor_feature():
"""次要功能测试"""
assert True
@allure.severity(allure.severity_level.TRIVIAL)
def test_trivial_feature():
"""轻微功能测试"""
assert True
按优先级运行测试:
# 只运行阻塞级别的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-severities=blocker
# 运行阻塞和严重级别的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-severities=blocker,critical
4.5 @allure.feature – 功能分类
使用 @allure.feature 可以将测试用例按功能模块分类。
示例:
import allure
@allure.feature("用户管理")
def test_create_user():
"""创建用户"""
assert True
@allure.feature("用户管理")
def test_delete_user():
"""删除用户"""
assert True
@allure.feature("订单管理")
def test_create_order():
"""创建订单"""
assert True
@allure.feature("订单管理")
def test_cancel_order():
"""取消订单"""
assert True
4.6 @allure.story – 用户故事
@allure.story 通常与 @allure.feature 配合使用,表示更细粒度的用户故事。
示例:
import allure
@allure.feature("用户管理")
@allure.story("用户注册")
def test_user_register():
"""用户注册"""
assert True
@allure.feature("用户管理")
@allure.story("用户登录")
def test_user_login():
"""用户登录"""
assert True
@allure.feature("用户管理")
@allure.story("用户注销")
def test_user_logout():
"""用户注销"""
assert True
@allure.feature("订单管理")
@allure.story("创建订单")
def test_create_order():
"""创建订单"""
assert True
@allure.feature("订单管理")
@allure.story("查看订单")
def test_view_order():
"""查看订单"""
assert True
按功能或故事运行测试:
# 只运行"用户管理"功能的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-features="用户管理"
# 只运行"用户登录"故事的测试
pytest test_example.py --alluredir=./allure-results -s -v --allure-stories="用户登录"
4.7 @allure.suite – 测试套件
使用 @allure.suite 可以将测试用例分组到不同的测试套件中。
示例:
import allure
@allure.suite("冒烟测试")
def test_smoke_1():
"""冒烟测试 1"""
assert True
@allure.suite("冒烟测试")
def test_smoke_2():
"""冒烟测试 2"""
assert True
@allure.suite("回归测试")
def test_regression_1():
"""回归测试 1"""
assert True
@allure.suite("回归测试")
def test_regression_2():
"""回归测试 2"""
assert True
4.8 @allure.tag – 标签
使用 @allure.tag 可以为测试用例添加标签,方便分类和筛选。
示例:
import allure
@allure.tag("API", "快速")
def test_api_quick():
"""快速 API 测试"""
assert True
@allure.tag("UI", "慢速")
def test_ui_slow():
"""慢速 UI 测试"""
assert True
@allure.tag("数据库", "重要")
def test_database_important():
"""重要的数据库测试"""
assert True
4.9 组合使用多个装饰器
在实际项目中,通常会组合使用多个装饰器:
示例:
import allure
import pytest
@allure.feature("用户管理")
@allure.story("用户登录")
@allure.severity(allure.severity_level.BLOCKER)
@allure.title("测试管理员登录功能")
@allure.description("""
测试管理员登录功能:
1. 输入正确的管理员账号和密码
2. 验证登录成功
3. 检查用户权限
""")
def test_admin_login():
"""测试管理员登录"""
with allure.step("打开登录页面"):
print("打开登录页面")
with allure.step("输入管理员账号和密码"):
username = "admin"
password = "admin123"
print(f"输入用户名: {username}")
print(f"输入密码: {password}")
with allure.step("点击登录按钮"):
print("点击登录按钮")
with allure.step("验证登录成功"):
assert True
5. Allure 附件功能
5.1 添加截图
在 UI 自动化测试中,截图是非常重要的调试工具。Allure 支持在测试过程中添加截图。
示例 1:基本截图
import allure
from PIL import Image
import io
def test_with_screenshot():
"""测试带截图"""
# 模拟截图(实际项目中从 Selenium 等工具获取)
img = Image.new('RGB', (800, 600), color='red')
img_bytes = io.BytesIO()
img.save(img_bytes, format='PNG')
img_bytes.seek(0)
# 添加截图到 Allure 报告
allure.attach(
img_bytes.read(),
name="登录页面截图",
attachment_type=allure.attachment_type.PNG
)
assert True
示例 2:Selenium 截图
import allure
from selenium import webdriver
def test_login_with_screenshot():
"""登录测试带截图"""
driver = webdriver.Chrome()
try:
driver.get("https://example.com/login")
# 截图并添加到报告
screenshot = driver.get_screenshot_as_png()
allure.attach(
screenshot,
name="登录页面",
attachment_type=allure.attachment_type.PNG
)
# 执行登录操作
driver.find_element_by_id("username").send_keys("admin")
driver.find_element_by_id("password").send_keys("123456")
# 登录后截图
driver.find_element_by_id("login-btn").click()
screenshot_after = driver.get_screenshot_as_png()
allure.attach(
screenshot_after,
name="登录后页面",
attachment_type=allure.attachment_type.PNG
)
assert True
finally:
driver.quit()
示例 3:失败时自动截图
import allure
import pytest
from selenium import webdriver
@pytest.fixture(scope="function")
def driver():
"""WebDriver fixture"""
driver = webdriver.Chrome()
yield driver
# 如果测试失败,自动截图
if pytest.current_test_failed:
screenshot = driver.get_screenshot_as_png()
allure.attach(
screenshot,
name="失败截图",
attachment_type=allure.attachment_type.PNG
)
driver.quit()
def test_login_fail_auto_screenshot(driver):
"""测试失败时自动截图"""
driver.get("https://example.com/login")
# 故意让测试失败
assert False, "测试失败,应该自动截图"
5.2 添加文本附件
示例:
import allure
def test_with_text_attachment():
"""测试带文本附件"""
# 添加普通文本
allure.attach(
"这是测试日志信息n包含多行内容",
name="测试日志",
attachment_type=allure.attachment_type.TEXT
)
# 添加 JSON 数据
import json
data = {"username": "admin", "status": "active"}
allure.attach(
json.dumps(data, indent=2, ensure_ascii=False),
name="用户数据",
attachment_type=allure.attachment_type.JSON
)
assert True
5.3 添加 HTML 附件
示例:
import allure
def test_with_html_attachment():
"""测试带 HTML 附件"""
html_content = """
<html>
<head><title>测试页面</title></head>
<body>
<h1>这是测试 HTML 内容</h1>
<p>包含一些测试信息</p>
<table border="1">
<tr><th>用户名</th><th>状态</th></tr>
<tr><td>admin</td><td>active</td></tr>
</table>
</body>
</html>
"""
allure.attach(
html_content,
name="测试页面",
attachment_type=allure.attachment_type.HTML
)
assert True
5.4 添加文件附件
示例:
import allure
def test_with_file_attachment():
"""测试带文件附件"""
# 读取文件内容
with open("test_data.txt", "r", encoding="utf-8") as f:
file_content = f.read()
# 添加文件附件
allure.attach(
file_content,
name="测试数据文件",
attachment_type=allure.attachment_type.TEXT
)
assert True
5.5 附件类型列表
Allure 支持以下附件类型:
allure.attachment_type.TEXT # 文本
allure.attachment_type.CSV # CSV 文件
allure.attachment_type.TSV # TSV 文件
allure.attachment_type.URI_LIST # URI 列表
allure.attachment_type.HTML # HTML
allure.attachment_type.XML # XML
allure.attachment_type.JSON # JSON
allure.attachment_type.YAML # YAML
allure.attachment_type.PNG # PNG 图片
allure.attachment_type.JPG # JPG 图片
allure.attachment_type.SVG # SVG 图片
allure.attachment_type.GIF # GIF 图片
allure.attachment_type.BMP # BMP 图片
allure.attachment_type.WEBM # WEBM 视频
allure.attachment_type.MP4 # MP4 视频
allure.attachment_type.PDF # PDF 文件
6. Allure 环境信息配置
6.1 什么是环境信息
环境信息用于记录测试执行的环境,包括操作系统、Python 版本、浏览器版本等。这些信息会在 Allure 报告的”Environment”部分显示。
6.2 创建环境配置文件
创建 environment.properties 文件:
# 操作系统信息
OS=Windows 10
OS.Version=10.0.19045
# Python 信息
Python.Version=3.9.0
Pytest.Version=7.0.0
# 浏览器信息
Browser=Chrome
Browser.Version=91.0
# 测试环境
Environment=Test
Base.URL=https://test.example.com
# 数据库信息
Database=MySQL
Database.Version=8.0
6.3 使用环境配置文件
方法 1:手动指定环境文件
# 将 environment.properties 放在 allure-results 目录中
pytest test_example.py --alluredir=./allure-results
# 手动复制 environment.properties 到 allure-results 目录
copy environment.properties allure-results/
# 生成报告
allure generate ./allure-results -o ./allure-report --clean
方法 2:使用 pytest fixture 自动生成
import pytest
import allure
import platform
import sys
@pytest.fixture(scope="session", autouse=True)
def configure_allure_environment():
"""配置 Allure 环境信息"""
environment = {
"OS": platform.system(),
"OS Version": platform.version(),
"Python Version": sys.version,
"Pytest Version": pytest.__version__,
}
# 写入环境信息到 allure-results 目录
import os
allure_dir = "./allure-results"
os.makedirs(allure_dir, exist_ok=True)
env_file = os.path.join(allure_dir, "environment.properties")
with open(env_file, "w", encoding="utf-8") as f:
for key, value in environment.items():
f.write(f"{key}={value}n")
yield
6.4 动态添加环境信息
示例:
import allure
import platform
import sys
def test_with_environment_info():
"""测试带环境信息"""
# 动态添加环境信息
allure.dynamic.environment(
OS=platform.system(),
Python=sys.version,
Pytest=pytest.__version__
)
assert True
7. Allure 历史记录
7.1 什么是历史记录
Allure 历史记录功能可以保存测试执行的历史数据,用于:
- 查看测试趋势
- 对比不同时间的测试结果
- 分析测试稳定性
7.2 启用历史记录
方法 1:使用 allure-results 目录结构
# 第一次运行
pytest test_example.py --alluredir=./allure-results
allure generate ./allure-results -o ./allure-report --clean
# 第二次运行(历史记录会自动保存)
pytest test_example.py --alluredir=./allure-results
allure generate ./allure-results -o ./allure-report
# 注意:不要使用 --clean,这样会保留历史记录
方法 2:使用 CI/CD 集成
# .github/workflows/test.yml 示例
name: Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: |
pytest --alluredir=./allure-results
- name: Generate report
run: |
allure generate ./allure-results -o ./allure-report
- name: Archive report
uses: actions/upload-artifact@v2
with:
name: allure-report
path: allure-report
7.3 查看历史趋势
在 Allure 报告的”Graphs”页面,可以查看:
- 测试用例数量的趋势
- 通过率趋势
- 失败率趋势
- 执行时间趋势
8. 完整的实战示例
8.1 示例 1:用户登录测试
创建 test_login.py:
import allure
import pytest
from selenium import webdriver
import time
@allure.feature("用户管理")
@allure.story("用户登录")
class TestLogin:
"""用户登录测试类"""
@pytest.fixture(scope="class")
def driver(self):
"""WebDriver fixture"""
driver = webdriver.Chrome()
yield driver
driver.quit()
@allure.title("测试管理员登录")
@allure.severity(allure.severity_level.BLOCKER)
@allure.description("""
测试管理员登录功能:
1. 打开登录页面
2. 输入管理员账号和密码
3. 点击登录按钮
4. 验证登录成功
""")
def test_admin_login(self, driver):
"""测试管理员登录"""
with allure.step("打开登录页面"):
driver.get("https://example.com/login")
time.sleep(1)
screenshot = driver.get_screenshot_as_png()
allure.attach(
screenshot,
name="登录页面",
attachment_type=allure.attachment_type.PNG
)
with allure.step("输入管理员账号和密码"):
driver.find_element_by_id("username").send_keys("admin")
driver.find_element_by_id("password").send_keys("admin123")
allure.attach(
"用户名: adminn密码: admin123",
name="登录信息",
attachment_type=allure.attachment_type.TEXT
)
with allure.step("点击登录按钮"):
driver.find_element_by_id("login-btn").click()
time.sleep(2)
screenshot = driver.get_screenshot_as_png()
allure.attach(
screenshot,
name="登录后页面",
attachment_type=allure.attachment_type.PNG
)
with allure.step("验证登录成功"):
assert "dashboard" in driver.current_url
assert driver.find_element_by_id("user-info").is_displayed()
@allure.title("测试普通用户登录")
@allure.severity(allure.severity_level.NORMAL)
def test_user_login(self, driver):
"""测试普通用户登录"""
with allure.step("打开登录页面"):
driver.get("https://example.com/login")
with allure.step("输入普通用户账号和密码"):
driver.find_element_by_id("username").send_keys("user")
driver.find_element_by_id("password").send_keys("user123")
with allure.step("点击登录按钮"):
driver.find_element_by_id("login-btn").click()
time.sleep(2)
with allure.step("验证登录成功"):
assert "dashboard" in driver.current_url
@allure.title("测试登录失败(错误密码)")
@allure.severity(allure.severity_level.NORMAL)
def test_login_failed(self, driver):
"""测试登录失败"""
with allure.step("打开登录页面"):
driver.get("https://example.com/login")
with allure.step("输入错误的密码"):
driver.find_element_by_id("username").send_keys("admin")
driver.find_element_by_id("password").send_keys("wrong_password")
with allure.step("点击登录按钮"):
driver.find_element_by_id("login-btn").click()
time.sleep(2)
with allure.step("验证登录失败提示"):
error_msg = driver.find_element_by_id("error-message").text
allure.attach(
f"错误信息: {error_msg}",
name="错误信息",
attachment_type=allure.attachment_type.TEXT
)
assert "密码错误" in error_msg
运行测试:
pytest test_login.py --alluredir=./allure-results -v
allure serve ./allure-results
8.2 示例 2:API 测试
创建 test_api.py:
import allure
import pytest
import requests
import json
@allure.feature("API 测试")
class TestAPI:
"""API 测试类"""
BASE_URL = "https://api.example.com"
@allure.story("用户 API")
@allure.title("测试获取用户信息")
@allure.severity(allure.severity_level.CRITICAL)
def test_get_user_info(self):
"""测试获取用户信息"""
user_id = 1
with allure.step(f"发送 GET 请求获取用户 {user_id} 的信息"):
url = f"{self.BASE_URL}/users/{user_id}"
response = requests.get(url)
allure.attach(
f"请求 URL: {url}n请求方法: GET",
name="请求信息",
attachment_type=allure.attachment_type.TEXT
)
with allure.step("验证响应状态码"):
assert response.status_code == 200
allure.attach(
f"状态码: {response.status_code}",
name="响应状态码",
attachment_type=allure.attachment_type.TEXT
)
with allure.step("验证响应数据"):
data = response.json()
allure.attach(
json.dumps(data, indent=2, ensure_ascii=False),
name="响应数据",
attachment_type=allure.attachment_type.JSON
)
assert data["id"] == user_id
assert "name" in data
@allure.story("用户 API")
@allure.title("测试创建用户")
@allure.severity(allure.severity_level.CRITICAL)
def test_create_user(self):
"""测试创建用户"""
new_user = {
"name": "测试用户",
"email": "test@example.com",
"age": 25
}
with allure.step("发送 POST 请求创建用户"):
url = f"{self.BASE_URL}/users"
response = requests.post(url, json=new_user)
allure.attach(
json.dumps(new_user, indent=2, ensure_ascii=False),
name="请求数据",
attachment_type=allure.attachment_type.JSON
)
with allure.step("验证创建成功"):
assert response.status_code == 201
data = response.json()
allure.attach(
json.dumps(data, indent=2, ensure_ascii=False),
name="响应数据",
attachment_type=allure.attachment_type.JSON
)
assert data["name"] == new_user["name"]
assert "id" in data
@allure.story("订单 API")
@allure.title("测试获取订单列表")
@allure.severity(allure.severity_level.NORMAL)
def test_get_orders(self):
"""测试获取订单列表"""
with allure.step("发送 GET 请求获取订单列表"):
url = f"{self.BASE_URL}/orders"
response = requests.get(url)
with allure.step("验证响应"):
assert response.status_code == 200
orders = response.json()
allure.attach(
f"订单数量: {len(orders)}",
name="订单统计",
attachment_type=allure.attachment_type.TEXT
)
assert isinstance(orders, list)
运行测试:
pytest test_api.py --alluredir=./allure-results -v
allure serve ./allure-results
8.3 示例 3:数据库测试
创建 test_database.py:
import allure
import pytest
import pymysql
@allure.feature("数据库测试")
class TestDatabase:
"""数据库测试类"""
@pytest.fixture(scope="class")
def db_connection(self):
"""数据库连接 fixture"""
connection = pymysql.connect(
host='localhost',
user='test',
password='test123',
database='test_db',
charset='utf8mb4'
)
yield connection
connection.close()
@allure.story("用户表操作")
@allure.title("测试查询用户")
@allure.severity(allure.severity_level.CRITICAL)
def test_query_user(self, db_connection):
"""测试查询用户"""
with allure.step("执行 SQL 查询"):
cursor = db_connection.cursor()
sql = "SELECT * FROM users WHERE id = %s"
cursor.execute(sql, (1,))
result = cursor.fetchone()
cursor.close()
allure.attach(
f"SQL: {sql}n参数: (1,)n结果: {result}",
name="SQL 执行信息",
attachment_type=allure.attachment_type.TEXT
)
with allure.step("验证查询结果"):
assert result is not None
assert result[0] == 1
@allure.story("用户表操作")
@allure.title("测试插入用户")
@allure.severity(allure.severity_level.CRITICAL)
def test_insert_user(self, db_connection):
"""测试插入用户"""
with allure.step("执行 SQL 插入"):
cursor = db_connection.cursor()
sql = "INSERT INTO users (name, email) VALUES (%s, %s)"
cursor.execute(sql, ("测试用户", "test@example.com"))
db_connection.commit()
user_id = cursor.lastrowid
cursor.close()
allure.attach(
f"SQL: {sql}n参数: ('测试用户', 'test@example.com')n新用户ID: {user_id}",
name="SQL 执行信息",
attachment_type=allure.attachment_type.TEXT
)
with allure.step("验证插入成功"):
assert user_id > 0
运行测试:
pytest test_database.py --alluredir=./allure-results -v
allure serve ./allure-results