:"太长了,我就想知道哪些用例没通过?跟上周比怎么样?失败的用例是谁负责的?"那一刻我突然意识到:不是领导不重视测试,而是我交出去的东西,本身就不是给决策者看的。Excel表格是测试工程师的内部语言,而领导需要的是一目了然的结论——哪些通过、哪些失败、风险在哪里、趋势是好是坏。
后来我换了种方式,把同样的测试结果导进Allure生成了一张可视化报告。报告里有一张通过率饼图、一条历史趋势折线图,每个失败的用例点进去能看到截图、请求参数和堆栈信息。领导拿着看了五分钟,主动问我三个问题:"这个失败的用例是什么情况?""上周的通过率比这周高多少?""能不能把迭代趋势图发给我?"三个问题让我确认了——他真的在看,而且看懂了
这就是Allure的价值所在:让测试结果变成一种可以对话的沟通语言,而不只是一堆数据的罗列。
01 环境搭建——3步跑通首个报告
1.1 先说说我的背景
我入职的时候,团队的测试报告流程是这样的:测试跑完,导出JUnit XML,用Python脚本转成Excel,测试组长手动填写汇总邮件,每周五下午定时发给团队。这个流程维持了三年,中间换过人,但没人想过改它——大家都习惯了。
我第一次用Allure,是自己私下搭着玩的。当时团队正好接了一个新项目,接口有七八十个,手工整理报告已经明显力不从心。我用Allure跑了第一张报告,发给开发看,他回了一句:"这比之前的Excel好认多了。"就这么一句反馈,让我决定把这个工具推进团队。
1.2 安装依赖
Allure分为两部分:一部分是Python插件(allure-pytest),负责在测试运行时收集数据;另一部分是命令行工具,负责把收集到的数据渲染成HTML报告。两部分都要装。
先装Python插件:
pip install allure-pytest然后装命令行工具。这个不在PyPI上,需要单独安装,不同系统方法不同:
# Windows:用scoop安装(类似macOS的Homebrew)Set-ExecutionPolicy RemoteSigned -Scope CurrentUseriwr -useb get.scoop.sh | iexscoop install allure# macOS:用Homebrewbrew install allure# Linux:手动下载(以2.25.0版本为例)wget https://github.com/allure-framework/allure2/releases/download/2.25.0/allure-2.25.0.tgztar -zxvf allure-2.25.0.tgz# 将allure/bin加入PATH环境变量
装完之后验证一下:
allure --version看到版本号就说明安装成功了。
1.3 写个最简单的用例跑起来
找个空目录,创建test_demo.py:
# test_demo.py - 先跑通再说def test_addition():"""测试加法运算"""result = 1 + 1assert result == 2, "1加1应该等于2"def test_string_concat():"""测试字符串拼接"""result = "Hello" + " " + "World"assert result == "Hello World"
然后运行测试,同时让Allure收集数据:
# --alluredir 指定数据存放目录pytest test_demo.py --alluredir=./allure-results
allure-results文件夹,里面是一堆JSON文件——这就是Allure收集到的原始数据。1.4 启动报告
数据有了,现在渲染成报告。两种方式:
方式一:allure serve(推荐本地调试)
allure serve ./allure-results这个命令会自动启动本地HTTP服务并打开浏览器。关掉终端窗口,服务就停了。
方式二:allure generate + allure open(生成持久报告)
# 生成报告到指定目录allure generate ./allure-results -o ./allure-report --clean# 启动服务查看allure open ./allure-report
💡 小提示 不要直接双击 |

02 步骤嵌套——让报告自己讲故事
2.1 为什么要嵌套步骤
我们团队真正感受到Allure价值,是从这一步开始的。
以前测试报告里写"登录失败",领导问"哪个环节失败的?"我得重新跑一遍用例,边跑边截图,再贴回Excel里说明。开发那边也是一肚子火——测试报告写的是"登录失败",他得花半小时才能定位到是密码加密那块的问题。
引入步骤嵌套之后,报告变成了这样:
# 引入Allure步骤装饰器import allure@allure.step("打开登录页面")def open_login_page():# driver.get("https://example.com/login")return True@allure.step("输入用户名:{username}")def input_username(username):# driver.find_element(By.ID, "username").send_keys(username)return True@allure.step("点击登录按钮")def click_login_button():# driver.find_element(By.ID, "login-btn").click()return Truedef test_login():open_login_page()input_username("testuser")click_login_button()assert True
注意@allure.step("输入用户名:{username}")里的{username},运行时会被替换成实际传入的值"testuser"。报告里显示的就是"输入用户名:testuser",不需要你在代码里写字符串拼接。
2.2 嵌套步骤:复杂流程的分层展示
一个复杂的业务流程,可以拆成多层步骤。上线前的冒烟测试用例,光"提交订单"这一个操作,背后就涉及商品校验、库存扣减、支付调用、物流下发等多个环节。用嵌套步骤就能把这种层级关系清晰呈现出来。
import allure@allure.step("选择商品:{name}")def select_product(name):# 点击商品 → 加入购物车pass@allure.step("填写收货地址")def fill_address(city, detail):# 输入城市 + 详细地址pass@allure.step("选择支付方式:{method}")def select_payment(method):# 选择支付渠道pass@allure.step("提交订单")def submit_order():# 点击提交按钮pass@allure.step("下单流程:购买{name}")def place_order(name, city, address, payment_method):# 顶层流程:调用四个子步骤select_product(name)fill_address(city, address)select_payment(payment_method)submit_order()@allure.feature("订单模块")@allure.story("下单流程")def test_place_order():place_order(name="iPhone 15 Pro",city="北京",address="朝阳区望京街道xxx号",payment_method="微信支付")assert True
运行后在报告里点击"下单流程:购买iPhone 15 Pro",会展开四个子步骤,每个步骤都显示耗时、状态,还可以继续展开看下一级详情。这种树状结构非常适合描述业务流程长、步骤多的测试场景。
2.3 步骤里加附件:截图、响应、日志全都有
光有步骤名称还不够,有时候我们要把截图、接口响应、错误日志直接嵌到报告里。开发点开失败用例,就能直接看到请求参数和返回内容,不需要你额外截图发邮件。
import allureimport json@allure.step("调用登录接口")def call_login_api(username, password):response = {"code": 200,"message": "登录成功","data": {"token": "eyJhbGciOiJIUzI1NiIs...","user_id": 12345}}# 附加JSON响应体到报告allure.attach(json.dumps(response, indent=2, ensure_ascii=False),name="接口响应",attachment_type=allure.attachment_type.JSON)return response@allure.step("截取页面截图")def take_screenshot(driver):# 将截图附加到报告allure.attach(driver.get_screenshot_as_png(),name="页面截图",attachment_type=allure.attachment_type.PNG)
allure.attach支持多种格式:JSON、XML、HTML、PNG、JPEG、SVG、CSV。指定不同的attachment_type,报告会自动渲染对应格式。
我们团队用的一个技巧是在conftest.py里注册一个全局钩子,测试失败时自动截图:
import pytestimport allure@pytest.hookimpl(hookwrapper=True)def pytest_runtest_makereport(item, call):outcome = yieldreport = outcome.get_result()# 只在测试失败时自动截图if report.when == "call" and report.failed:if "driver" in item.funcargs:driver = item.funcargs["driver"]allure.attach(driver.get_screenshot_as_png(),name="失败截图",attachment_type=allure.attachment_type.PNG)

03 分类与标记——给用例贴标签
3.1 三层标签体系
用例多了以后,按什么维度组织是个问题。Allure提供了三层标签体系:
@allure.feature—— 模块(顶层) @allure.story—— 场景(第二层) @allure.title—— 用例标题(第三层)
import allure@allure.feature("用户模块") # 模块@allure.story("用户登录") # 场景@allure.title("正常登录成功") # 用例标题def test_login_success():assert True@allure.feature("用户模块")@allure.story("用户登录")@allure.title("密码错误登录失败")def test_login_wrong_password():assert True@allure.feature("订单模块")@allure.story("创建订单")@allure.title("购物车商品下单")def test_create_order_from_cart():assert True
3.2 严重程度:让BLOCKER级别的失败先被发现
不是所有失败的用例优先级都一样。Allure内置了五个严重程度等级:
import allure@allure.severity(allure.severity_level.BLOCKER)def test_system_startup():"""系统无法启动,阻塞所有测试"""assert False@allure.severity(allure.severity_level.CRITICAL)def test_payment_processing():"""支付流程失败,可能导致资金损失"""assert True@allure.severity(allure.severity_level.NORMAL)def test_search_function():"""搜索功能,返回结果有偏差"""assert True@allure.severity(allure.severity_level.MINOR)def test_button_style():"""按钮颜色与设计稿不一致"""assert True@allure.severity(allure.severity_level.TRIVIAL)def test_ui_typo():"""页面提示文字多了一个空格"""assert True
3.3 自定义标签:管理责任人、环境、优先级
内置标签不够用的时候,可以自定义标签。我们团队用自定义标签管理了三件事:
import allure@allure.label("owner", "张三") # 责任人@allure.label("priority", "P0") # 优先级@allure.label("layer", "API") # 测试层次:API / UI / 集成@allure.tag("冒烟测试", "回归测试") # 测试类型标签def test_api_core_function():assert True
通过owner标签,可以在报告里按负责人筛选——发周报的时候,直接生成每人负责模块的通过率,一键导出,不需要手动统计。
3.4 参数化用例:一张图展示所有参数组合
import allureimport pytest@allure.feature("计算器")@allure.story("加法运算")@allure.title("加法测试: {a} + {b} = {expected}")@pytest.mark.parametrize("a, b, expected", [(1, 1, 2),(2, 3, 5),(10, 20, 30),(-1, 1, 0),])def test_addition(a, b, expected):result = a + bassert result == expected
@allure.title里的占位符会自动替换成实际参数值,每组参数在报告里显示为独立用例,不需要你为每组参数单独写测试函数。
04 环境信息与趋势图——让报告更专业
4.1 让报告展示测试环境
光有测试结果还不够,报告里应该包含测试时的环境信息。Allure支持通过environment.properties文件注入环境信息,这些信息会显示在报告首页。
# environment.properties# 放在项目根目录,与allure-results同级Python.Version=3.11.0Pytest.Version=7.4.3Allure.Version=2.25.0Browser=Chrome 120.0Browser.Driver=ChromeDriver 120.0Test.Environment=测试环境API.BaseURL=https://api-test.example.comDB.Host=192.168.1.100DB.Port=3306DB.Name=test_dbDB.Version=MySQL 8.0
conftest.py里写:import osimport platformimport datetimeimport pytestdef write_environment_properties():env_info = {"OS": platform.system(),"Python.Version": platform.python_version(),"Test.Time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"Pytest.Version": pytest.__version__,}results_dir = "./allure-results"os.makedirs(results_dir, exist_ok=True)with open(os.path.join(results_dir, "environment.properties"),"w", encoding="utf-8") as f:\n for key, value in env_info.items():f.write(f"{key}={value}\n")@pytest.fixture(scope="session", autouse=True)def setup_environment():write_environment_properties()
这个fixture加在conftest.py里,每次运行测试都会自动生成环境信息,不需要手动维护文件。
4.2 趋势图:让领导看到变化趋势
趋势图是Allure最打动领导的功能之一。它会记录每次测试执行的结果,生成通过率随时间变化的折线图。
本地测试时保留历史数据:
# 首次运行pytest tests/ --alluredir=./allure-results# 第二次运行(不要加--clean-alluredir,让数据追加)pytest tests/ --alluredir=./allure-results# 生成的报告会包含两次运行的对比allure serve ./allure-results
趋势图的价值在于:当某次构建后通过率突然下降时,可以很直观地看到是从哪次引入的问题,而不是凭记忆猜测。我们团队有个不成文的规定——周报里必须附趋势图,连续两周下滑的模块要在周会上专项讨论。
4.3 附件里放视频
UI自动化测试中,偶发性失败最难定位。截图是静态的,有时候看不出操作顺序。我们引入了失败自动录屏,把MP4视频嵌入报告,开发回放一遍就能复现问题。
import allureimport os@allure.step("附加测试视频")def attach_video(video_path):if os.path.exists(video_path):with open(video_path, "rb") as f:\n allure.attach(\n f.read(),\n name="测试执行视频",attachment_type=allure.attachment_type.MP4)

05 Jenkins集成——每次构建自动出报告
5.1 为什么要集成到Jenkins
本地跑Allure没问题,但真正的价值在于让报告成为CI/CD流程的天然产物——代码提交 → 自动构建 → 测试执行 → 报告生成,全程无需人工干预。
我们团队推进Allure的时候,Jenkins集成是最难说服人的环节。开发和运维的顾虑是:"这东西搞进来,Jenkins配置会不会变得很复杂?出了问题谁维护?"我当时的回答是:"配置一次,以后不用管。报告自动生成,失败自动通知。"后来这个承诺基本兑现了,Jenkins的Allure集成比我想象中稳定得多。
5.2 安装Allure插件
Jenkins本身不支持Allure,需要先装插件:
进入 Jenkins → Manage Jenkins → Manage Plugins 切换到 Available 标签页,搜索"Allure Jenkins Plugin" 勾选安装,安装完成后重启Jenkins 进入 Manage Jenkins → Global Tool Configuration 找到 Allure Commandline,点击 Add Allure Commandline Name填 allure,勾选 Install automatically,版本选择较新的
Jenkins会自动下载并管理Allure命令行工具,不需要在服务器上手动安装。
5.3 自由风格项目配置
对于自由风格项目,配置分两步:
第一步:构建步骤(Execute shell)
# 安装依赖python3 -m venv venv. venv/bin/activatepip install -r requirements.txtpip install allure-pytest# 运行测试,生成数据到allure-results目录pytest tests/ --alluredir=./allure-results --clean-alluredir -v --tb=short
第二步:构建后步骤(Allure Report)
添加"Allure Report"构建后步骤:
Results 路径填 allure-results(与构建步骤中的目录一致)Report 路径默认即可 勾选 "Always link to last build"(始终在构建历史中显示报告链接)
这里有个细节:--clean-alluredir参数只在本地调试时需要加,CI/CD环境里Jenkins每次构建都是全新的workspace,不存在覆盖问题,所以CI里不需要这个参数。
5.4 报告持久化与保留策略
默认情况下,Jenkins会保留每次构建的报告页面。但构建次数多了会占用大量磁盘空间,需要配置保留策略。
在"Allure Report"配置中,找到 Report retention policy:
- Keep last N builds
保留近N次构建的报告(推荐设为20~30) - Keep for N days
按时间保留(推荐设为30天)
我们团队选的是"保留最近25次",超过25次的历史报告基本没人在意,太久远的数据反而干扰判断。
5.5 Pipeline项目:Jenkinsfile配置
如果项目使用Pipeline,推荐用Jenkinsfile管理配置,版本可控、便于审查。下面是一个真实可用的Jenkinsfile模板:
// Jenkinsfile - Allure测试报告Pipelinepipeline {agent anyenvironment {ALLURE_RESULTS = 'allure-results'PYTHON_VERSION = '3.11'}triggers {// 定时触发:每天凌晨2点执行cron('0 2 * * *')// 代码提交触发(需配置GitLab webhook)gitlab(triggerOnPush: true, triggerOnMergeRequest: true)}stages {stage('环境准备') {steps {echo '准备Python环境...'sh '''python3 -m venv venv. venv/bin/activatepip install -r requirements.txtpip install allure-pytest'''}}stage('运行测试') {steps {echo '执行测试用例...'sh '''. venv/bin/activatepytest tests/ \\--alluredir=${ALLURE_RESULTS} \\-v \\--tb=short'''}}stage('生成报告') {steps {echo '生成Allure报告...'allure includeProperties: false,jdk: '',results: [[path: env.ALLURE_RESULTS]]}}}post {always {echo '构建后处理...'}failure {// 构建失败时发送钉钉通知dingtalk(robot: 'your-robot-id',type: 'MARKDOWN',title: '测试构建失败',text: ["### 测试构建失败","- 项目:${env.JOB_NAME}","- 构建:#${env.BUILD_NUMBER}","- 原因:测试用例执行失败","- 报告:[查看详情](${env.BUILD_URL}allure/)"])}success {echo '测试通过!'cleanWs()}}}/*** 使用说明:* 1. 将此文件放在项目根目录,命名为 Jenkinsfile* 2. Jenkins中创建 Pipeline 项目,选择 "Pipeline script from SCM"* 3. 配置Git仓库地址* 4. 确保Jenkins已安装 Allure Plugin 和 DingTalk Plugin* 5. 在 Jenkins 全局配置中添加 Allure 命令行工具*/
💡 钉钉通知配置细节 钉钉机器人的webhook地址需要在Jenkins的"DingTalk"插件配置里填入。创建机器人时,选择"自定义机器人",复制webhook URL即可。 通知消息里 |

06 实战:从0到1搭建Allure报告体系完整记录
📋 实战复盘:某团队Allure落地全记录
团队现状(落地前)
团队规模约12人,测试工程师5人。测试框架是Pytest,但报告用的是手工Excel汇总。每周五下午测试组长花2~3小时整理周报,关键数据靠记忆填充,经常出现数据对不上的情况。开发和测试之间经常因为"测试结论不清晰"产生摩擦。
用例:约180频率:每日形式:Excel成本:高
选型过程
对比了pytest-html和Allure,最终选Allure的原因有三个:
- 趋势图功能
领导明确要求能看到历史对比,pytest-html不支持 - 步骤嵌套
接口测试用例步骤多,嵌套展示能减少沟通成本 - Jenkins插件成熟度
Allure Jenkins Plugin社区活跃,文档完善
搭建步骤(耗时3天)
第1天(下午):本地环境搭通。安装依赖,跑通demo,发给组长和两位开发看demo,得到认可
第2天:在Jenkins测试环境配置流水线。遇到版本不匹配的问题(Allure CLI版本2.24,插件要求2.25以上),更新CLI后解决。生成第一张正式报告
第3天:将180条用例分批改造。第一批50条核心冒烟用例加装饰器,其余130条保持原样渐进推进。配置钉钉通知机器人
遇到的问题
- 中文乱码
Windows环境下conftest.py里加了UTF-8编码强制设置解决 - 历史趋势不显示
初期用--clean-alluredir参数导致历史数据被清,改为CI环境不加此参数 - 报告部署
Allure内置服务不稳定,改用Nginx代理静态报告目录,给团队固定访问地址
最终效果
报告整理时间:3小时 → 5分钟(自动化生成)
用例覆盖率:27% → 100%
开发满意度:"测试结论更清晰了"
团队反馈(落地3个月后)
"以前周五下午最怕交周报,现在报告自动生成,我只需要写几句结论就完事。""开发问问题的时候直接甩报告链接,比我截图发邮件清楚多了。""趋势图功能领导用得最勤,每周周会第一个点开看。""偶尔测试失败,截图和日志都在报告里,不需要我再解释半天了。"
可复制的行动清单
先在本地跑通demo,让leader和至少一名开发体验一下 在Jenkins测试环境搭一条流水线,跑通后再推广 用例改造分批进行,核心冒烟用例优先(影响最大的20%用例优先处理) 报告访问地址固定化(Nginx或内网静态服务),不要每次从Jenkins口进 失败通知渠道先用起来,让团队感受到"测试失败就有人知道"这个变化
07 避坑指南——4个常见问题
坑1:报告打开白屏
症状:双击index.html,浏览器显示白屏。
原因:Allure报告依赖HTTP服务加载资源,直接用file://协议打开会被浏览器的安全策略拦截。
解决:
# 必须通过HTTP服务访问allure serve ./allure-results# 或先生成报告,再用服务打开allure generate ./allure-results -o ./allure-report --cleanallure open ./allure-report
⚠ 分享报告的正确方式 不能直接把allure-report目录打包发给同事 ① 部署到Nginx/Apache等HTTP服务器上,给一个固定URL; ② 用 ③ 在CI里把报告上传到内网文件服务。 |
坑2:中文乱码
症状:报告中的中文显示为方块或问号。
原因:Windows系统默认编码是GBK,而Allure期望UTF-8。
解决:
# 方案一:conftest.py中强制设置编码import sysimport iosys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')# 方案二:确保Python文件保存为UTF-8编码(大部分IDE默认如此)
坑3:历史趋势不显示
症状:运行了多次测试,但报告里只有一次数据。
原因:--clean-alluredir参数在CI环境中每次构建都会清空结果目录,历史数据无法累积。
解决:CI/CD环境中不要加--clean-alluredir参数,让Jenkins的Allure插件自动管理历史数据保留策略。本地调试时可以加,方便每次清空重来
坑4:插件版本不匹配
症状:报告生成失败,报错"Allure version not supported"。
原因:Jenkins Allure插件版本与Allure命令行工具版本不兼容。
解决:在Jenkins的Global Tool Configuration中,将Allure Commandline的版本更新到较新版本(推荐2.25.0以上)。确保插件版本和CLI版本匹配
# 本地检查版本allure --version# Windows更新scoop update allure# macOS更新brew upgrade allure

08 Allure vs 其他工具对比 + 行动清单
工具横向对比
| 可视化程度 | |||
| 上手难度 | |||
| Jenkins集成 | |||
| 历史趋势 | |||
| 附件支持 | |||
| 多语言 |
选型建议:团队重视可视化、需要历史趋势数据、多人协作开发、CI/CD流程成熟的,选Allure不会后悔。想快速出结果、临时用一下、不想改代码的,pytest-html够用。遗留老项目里继续用unittest-xml也行,配合Jenkins JUnit插件也能看。
5步行动清单
- 今天:
装好Allure依赖,用本文的test_demo.py跑通第一个报告。整个过程不超过15分钟。 - 本周:
在现有测试项目里选5个核心用例,加 @allure.step和@allure.feature装饰器,生成一张带步骤的完整报告,发给开发看看效果。 - 本周:
在Jenkins测试环境搭一条流水线,跑通自动报告生成。流水线的价值在于让所有人看到"每次提交代码,报告就自动更新"这个过程。 - 下周一:
配置钉钉(或企业微信)通知机器人。失败时自动推送消息到群,这个功能对团队感知测试状态最有立竿见影的效果。 - 两周内:
把报告访问地址固定化——用Nginx代理allure-report目录,给团队一个收藏夹链接。每周周会前领导就能自己去看,不需要你再发邮件了。
测试报告的价值,不在于它有多好看,而在于它能不能让决策者快速理解测试结果。Allure帮我做到了一点:用图表说话,用数据服人。希望这篇文章也能帮到你
再多分享一个进阶操作:把Allure报告和团队协作工具打通。比如用@allure.label标注用例ID,报告里点击ID跳转到内部用例管理平台。失败用例自动在JIRA上创建缺陷单,附上报告链接和截图。这些集成都有成熟的方案,Allure的数据结构是开放的,给你留了很多定制空间。
:另外提醒一点:Allure的数据存在allure-results目录里的JSON文件里。如果你的团队已经在用其他数据看板(比如飞书多维表格、自建BI系统),可以把JSON数据解析后推送到那边,做自定义趋势图和统计。数据是开放的,报表格式由你说了算。
夜雨聆风