简介:Allure 2.13.9 是面向测试工程师与自动化开发者的开源测试报告生成工具安装包。它兼容 JUnit、TestNG、pytest 等主流测试框架,能够将执行结果转化为包含统计图表、步骤详情与失败原因分析的可视化报告,适合需要统一呈现和追踪测试质量的团队使用。压缩包以 rar 格式打包,整体约 16.29MB,内含 Allure 命令行工具及运行所需文件,下载解压后即可在测试流程中直接调用,快速生成或预览报告。该版本在性能与稳定性上有所优化,同时支持通过配置文件定制报告布局与样式,也可与 Jira、Trello 等项目管理工具集成,方便在报告中直接跟进缺陷。目前已有 386 人学习下载,是自动化测试、持续集成环节中报告生成与展示的常用稳定版本,能帮助团队更直观地评估测试结果,提高问题定位效率。
1. allure-2.13.9.rar 在 Windows 环境里的真实定位
如果你在浏览器里敲下allure-2.13.9.rar这个名字,大概率是从某个网盘、镜像站或同事的分享链接里拿到的安装包。Allure 是目前 Java 生态和 Python 生态里最常用的测试报告框架之一,2.13.9 这个版本发布于 2021 年,虽然在它之后有 2.14、2.15、2.16 等新版本,但 2.13.x 系列依然有不少存量项目在使用——尤其是那些锁定版本、不想被新版本行为变化影响的团队。这个 rar 压缩包本质上就是 Allure 命令行工具在 Windows 平台的发行包,解压后就能拿到bin/allure.bat,通过命令行把测试执行结果渲染成一套可交互、可历史对比、可分享的 HTML 报告。
这篇文章不打算只教你「解压到 D 盘然后设置环境变量」,那太浪费了。我会把这一条链路完整讲清楚:解压部署时应该注意什么,怎么在 Windows 上跑通第一个报告,怎么把 allure-results 目录和 pytest、JUnit 等框架打通,以及当你发现报告趋势图不显示、历史记录不回填、环境信息缺失时,应该从哪里下手排查。
2. 解压部署:allure-2.13.9.rar 的目录结构和环境变量配置
2.1 为什么拿到的是 rar 而不是 zip,以及怎么解压
Allure 官方在 GitHub Releases 页面提供的是 zip 压缩包,但国内很多镜像站和个人分享为了压缩率或者打包习惯,会重新压成 rar 格式。这个格式差异本身不影响使用,只要解压出来的目录结构完整就行。常见的解压工具有 WinRAR、7-Zip,命令行场景下也可以用7z x allure-2.13.9.rar来解压。
解压之前先看一眼文件大小,正常情况应该在 20MB 到 30MB 之间。如果文件只有几百 KB,那大概率是下载页面而不是安装包本身。解压时要保持目录结构完整,不要在解压过程中手动调整文件夹层级,因为bin、config、lib这些目录之间的相对路径是写死的,调整之后启动时会报找不到模块的错误。
注意:解压路径不要带空格和中文。Windows 上
C:\Program Files\allure这种路径虽然也能跑,但后续如果你用 Jenkins 或批处理脚本,带空格的路径会逼你到处加引号,很烦。我一般会放在D:\tools\allure-2.13.9这种纯英文路径下。
2.2 用命令验证解压结果是否完整
解压完成后,先别急着配环境变量,打开命令行切到解压目录,验证一下核心文件是否齐全。
cd /d D:\tools\allure-2.13.9 dir /s /b | findstr /i "allure.bat allure serve"这条命令把解压目录下的所有文件路径列出来,再筛选出包含allure.bat和allure serve的行。正常情况下你应该能看到bin\allure.bat和bin\allure-serve.bat这两个文件的存在。如果只看到了allure.bat而没有allure-serve.bat,说明打包的人可能做了裁剪,或者解压过程中丢失了文件。
然后再做一次启动级验证,直接用完整路径调用版本命令:
D:\tools\allure-2.13.9\bin\allure.bat --version能看到2.13.9的输出就说明 Java 环境和 Allure 本身的 jar 包都正常。如果这里报错说找不到java,那么下一步不是检查 Allure,而是先去装 JDK——Allure 2.13.x 要求 Java 8 及以上版本,实际上用 Java 8 或 Java 11 都行,用更高版本的 JDK 时我遇到过反射警告但不影响使用。
2.3 环境变量配置的两种落地方式
验证过了核心文件,接下来把bin目录加到系统 PATH 里。这里有两种做法,两种我都用过,但推荐第二种。
第一种做法是直接在系统环境变量里改 PATH,把D:\tools\allure-2.13.9\bin追加进去。这种方式一劳永逸,但副作用是所有终端窗口共享一套配置,如果团队里有人改了其他工具的 PATH 导致冲突,你这边也会被影响。
第二种做法是为 Allure 单独建一个ALLURE_HOME环境变量,然后在 PATH 里引用它:
setx /M ALLURE_HOME "D:\tools\allure-2.13.9" setx /M PATH "%PATH%;%ALLURE_HOME%\bin"这两种写法的区别在于可维护性。用ALLURE_HOME的方式,将来升级版本时只要把ALLURE_HOME指到新目录,PATH 不用动;而直接写绝对路径的方式,每次换版本都得改 PATH。注意setx命令设置的变量只对之后新开的进程生效,当前这个命令行窗口里还是看不到效果,所以配完之后要新开一个cmd或 PowerShell 窗口。
验证环境变量是否生效:
where allure allure --versionwhere命令会列出所有匹配的执行文件路径,如果输出了D:\tools\allure-2.13.9\bin\allure.bat,说明 PATH 没有问题。
2.4 rar 包里的 config 目录有什么可改的
解开 rar 包之后,config目录里有一个文件值得注意:allure.yml。这个文件定义了报告一些默认行为,我自己改过最多的配置是report-name和custom-logo。前者的作用是改报告左上角显示的标题文字,后者是替换 Allure 默认的 logo 图标。
贴一段我常用的allure.yml配置:
report-name: 测试报告 custom-logo: logo.png allure: directory: /d/allure-results report: directory: /d/allure-report注意directory和report.directory这两项,它们的含义是指定默认的测试结果目录和报告输出目录。如果你在项目里永远只用一个结果目录,写成绝对路径可以省去每次命令行里重复输入的麻烦。但如果你同时跑多个框架的测试,这个配置就要注释掉,否则每次都会覆盖同一个输入目录,报告数据会互相污染。
3. 从 allure-results 到 HTML 报告:核心命令与数据流转链路
3.1 先做一个最小实验:手写一个 results 目录
做个实验来理解 Allure 的工作机制。Allure 本身不采集数据,它只负责读取一个叫allure-results的目录,里面放着 JSON 文件,每个文件描述一个测试用例的结果、步骤、附件等。你可以不用任何测试框架,纯手写几个 JSON 来验证环境。
在某个空目录下新建allure-results文件夹,然后手动创建两个文件。
第一个文件test-case.json,描述一条测试用例:
{ "name": "验证登录接口响应时间", "status": "passed", "stage": "finished", "start": 1700000000000, "stop": 1700000000500, "steps": [ { "name": "发起登录请求", "status": "passed", "stage": "finished", "start": 1700000000100, "stop": 1700000000200 } ], "labels": [ { "name": "severity", "value": "blocker" } ] }第二个文件container.json,定义一个测试容器,相当于测试类或测试套件:
{ "name": "登录模块测试", "children": ["test-case.json 中的 uuid"], "befores": [], "afters": [] }需要说明的是,真实的 Allure 结果文件中会有唯一的uuid字段来关联容器和用例,这里手写只是为了验证流程,格式上并不严谨。跑实验的目的不是要求这两个 JSON 能被完美解析,而是要看命令本身能不能跑通、报告目录能不能生成。
3.2 用 allure generate 生成静态报告
现在打开终端,进入刚才创建allure-results目录的那一层,执行:
allure generate allure-results -o allure-report --clean拆解一下这条命令:
allure-results是输入目录,存放测试框架生成的原始 JSON 数据-o allure-report是报告输出目录,不指定时默认生成在当前目录的allure-report文件夹--clean表示输出目录已存在时先清空,避免新旧报告混在一起
执行完成后,allure-report目录里会出现一套完整的 HTML 静态资源。双击打开index.html,如果 JSON 数据能被正确解析,就能看到用例列表和步骤明细;如果解析失败,页面上只有空壳框架,没有用例数据。
生成报告之后,用浏览器打开 HTML 文件。直接用file://协议打开时,有些图表模块受浏览器安全策略限制无法渲染,这时候可以起一个本地服务来托管报告目录:
allure open allure-report这条命令会在默认浏览器中打开报告,并启动一个本地 HTTP 服务,端口默认是127.0.0.1:56789,也可以手写allure open -p 8765 allure-report来指定端口。
3.3 常用命令参数一览
Allure 命令很多,但实际项目里能用到的也就那么几个。我把这些命令整理成一张表,方便日常查阅。
| 命令 | 作用 | 常用参数 |
|---|---|---|
allure generate <input> | 生成静态 HTML 报告 | -o指定输出目录,--clean先清空再生成 |
allure open <report> | 打开报告并启动本地服务 | -p指定端口,默认 56789 |
allure serve <results> | 用临时目录生成报告并自动打开浏览器 | 不支持-o,报告在临时目录 |
allure --version | 查看当前版本 | 用于确认环境变量是否生效 |
allure serve与generate的区别值得说清楚。serve适合本地调试,它默认托管在一个临时目录,关掉服务之后报告就不在了;generate则把报告固化到磁盘上,适合作为 CI 产物保存或归档。在日常开发中我基本用serve看效果,在 Jenkins 里永远用generate。
3.4 历史趋势为什么是空的,以及正确的生成时机
很多人在本地跑完allure generate之后,打开报告发现 Overview 页的 Trends 图标是空的「No data」状态。这不是环境问题,而是生成顺序错了。
Allure 的历史数据来源有一个专门的名字叫history目录,它位于报告输出目录(allure-report)内,包含了history.json、duration.json、trend.json三个文件。每次生成报告时,Allure 会从之前的报告目录中读取这三个文件,然后把当前结果追加进去,再写入新报告。
如果第一次生成报告时,输出目录是空的或者不存在,那么自然没有历史数据可读,趋势表就是空的。要让趋势图持续累积数据,需要做到两点:
第一,每次生成报告之前,确保旧的allure-report目录没有被删除。在 CI 里这一点很容易被忽略,因为很多流水线脚本习惯在构建开始时把整个工作空间清空重建。
第二,不要混用serve和generate。serve每次都在临时目录里生成报告,不会保留上一轮的历史文件,所以用serve永远看不到趋势累积。
正确的循环看起来像这样:
allure generate allure-results -o allure-report --clean allure open allure-report只要不间断地复用同一个allure-report目录,Trends 图就会像滚雪球一样把每次跑批的数据都记录进去。
4. 把 allure-2.13.9 接入 pytest:从零到完整报告的最小工程
4.1 为什么优先推荐 pytest + allure-pytest 的组合
Java 世界里 Allure 通常配 JUnit 或 TestNG,在 Python 的世界里则是 pytest 最成熟。原因在于allure-pytest这个插件维护得很活跃,它提供了大量装饰器,能在测试执行时自动往allure-results目录写入 JSON 结果文件。不需要自己手工构造 JSON,也不需要改造测试逻辑,只要在 pytest 启动时加载插件即可。
安装依赖版本上要留意一个细节:Allure 命令行工具和allure-pytest插件是两个独立发布的组件。命令行用 2.13.9,插件版本可以不用完全对齐,但建议至少用 2.9 以上的版本,再低的话对steps、dynamic这类装饰器的支持不太完整。
安装命令如下:
pip install allure-pytest==2.9.45 pytest==7.4.0这里我锁了两个版本号,确保后面给的示例代码能在你本机稳定复现。如果你持有较新版本的allure-pytest,语法上兼容性一般没问题,但版本差异可能导致--allure-epics这类命令行过滤参数的行为有变化。
4.2 写一个带步骤和附件的测试用例
创建一个 Python 文件test_login.py,内容如下:
import pytest import allure import json @allure.feature("登录模块") @allure.story("密码登录") @allure.severity(allure.severity_level.BLOCKER) def test_login_success(): with allure.step("点击登录按钮"): assert True with allure.step("输入正确的用户名密码"): login_payload = {"username": "admin", "password": "admin123"} with allure.step("请求登录接口"): resp_json = {"code": 0, "msg": "success"} assert resp_json["code"] == 0 allure.attach( json.dumps(resp_json, ensure_ascii=False, indent=2), name="登录接口返回值", attachment_type=allure.attachment_type.JSON )这段代码覆盖了几个高频用法,逐一说一下具体含义:
@allure.feature对应报告 Behavior 页里的 Feature 层级,适合用来描述模块@allure.story对应 Story 层级,适合描述功能点@allure.severity给用例打上严重级别标签,报告里可以按 Blocker/Critical/Normal 等维度过滤with allure.step(...)会形成嵌套步骤,在报告里以可折叠的树形结构展示allure.attach把附加数据挂在用例上,支持 JSON、文本、PNG 截图等多种格式
除了装饰器,还可以在测试内部动态设置标题和描述:
@allure.title("登录成功 - 动态标题") def test_dynamic_title(): allure.dynamic.description("替换掉静态 description") assert Trueallure.dynamic系列适合数据驱动用例,因为每个用例实际执行时才确定参数值,装饰器里的静态写法反而不好做。
4.3 执行 pytest 并生成报告的完整命令链
测试代码写好了,接下来执行测试并生成报告。完整的命令链如下:
pytest test_login.py -s -q --alluredir=./allure-results --clean-alluredir allure generate ./allure-results -o ./allure-report --clean allure open ./allure-report逐条拆解:
第一条命令执行测试,--alluredir=./allure-results指结果输出目录,--clean-alluredir表示执行前清空旧结果。这个清空参数很重要,否则旧测试结果会和新结果混在一起,报告里会出现历史残留的用例。
第二条命令把结果目录渲染成报告目录,第三条命令在浏览器中打开。
如果你想跳过一次大的构建过程,还可以用allure serve快速预览:
pytest test_login.py --alluredir=./allure-results allure serve ./allure-resultsserve会自动生成临时报告并打开浏览器,适合快速迭代,但它不会累积历史趋势,所以最终沉淀报告还是要用generate。
4.4 清空结果目录的成本与选择
一个小问题:--clean-alluredir是每次都要加吗?
分场景讨论。在本地调试阶段,我推荐每次都加,因为本地尝试的次数多,旧结果文件很容易把报告搞得混乱;在 CI 里,构建环境每次都是全新的,结果目录本来就是空的,加不加无所谓,加上更保险。
如果不加这个参数,删除所有allure-results下的 JSON 文件这种操作就要自己管理。常用的清理方式是:
rm -rf allure-results但 Windows 的cmd不识别rm -rf,PowerShell 里又得写成Remove-Item -Recurse -Force,所以在 Windows 下直接用--clean-alluredir是最省事的。跑完上面这一套流程,打开报告应该能看到功能模块、用例列表、步骤追踪和附件展示。
5. 报告优化:环境变量、分类过滤和 3 个高频坑的排查方法
5.1 给报告加上环境信息
Allure 报告默认只展示用例本身的数据,但测试执行的环境信息(比如操作系统、Python 版本、测试环境的 Base URL)是不会自动出现的,需要在结果目录中放一个名为environment.properties的文件,注意是放在allure-results目录里,而不是报告目录里。
我一般是在测试代码中动态生成这个文件,这样每次跑批后环境信息跟着刷新。下面给一段conftest.py里的实现:
import os import platform import pytest from datetime import datetime @pytest.fixture(scope="session", autouse=True) def write_allure_environment(): env_dir = "allure-results" os.makedirs(env_dir, exist_ok=True) env_content = f""" os={platform.system()} python_version={platform.python_version()} hostname={os.getenv('COMPUTERNAME', 'unknown')} env_url=https://api-dev.example.com exec_time={datetime.now().strftime('%Y-%m-%d %H:%M:%S')} """ with open(os.path.join(env_dir, "environment.properties"), "w", encoding="utf-8") as f: f.write(env_content)生成报告后,Overview 页面左侧的 Environment 栏会展示这几项配置。如果报告里没有出现 Environment 栏,优先检查文件名是否写对了——必须是environment.properties,多一个字母或少一个字母都无效。文件内容格式也有讲究,每行一个key=value,不允许出现中文引号。
5.2 用 categories.json 精细分类失败原因
默认情况下,Allure 把失败的用例分为「Product defects」和「Test defects」两种。前者是断言失败,后者是测试代码本身报错。但这种分类太粗糙了,实际团队里你会更想区分「接口超时」「数据库连接失败」「环境问题」和「真正的产品 Bug」。
在allure-results目录下建一个categories.json就能覆盖默认分类。下面是一个常见的互联网业务团队配置:
[ { "name": "接口超时", "matchedStatuses": ["failed"], "messageRegex": ".*timeout.*|.*TimedOut.*" }, { "name": "数据库异常", "matchedStatuses": ["failed", "broken"], "messageRegex": ".*Connection refused.*|.*MySQL.*" }, { "name": "断言失败", "matchedStatuses": ["failed"], "messageRegex": ".*AssertionError.*" }, { "name": "环境问题", "matchedStatuses": ["broken"], "traceRegex": ".*environment.*|.*config.*" } ]这个 JSON 数组中的每个分类对象有几个关键字段:
name:报告中显示的类别名matchedStatuses:匹配哪个状态,可选passed、failed、broken、skipped、unknownmessageRegex:按异常消息匹配,Java 风格的日志文本也能匹配得到traceRegex:按堆栈跟踪匹配,命中堆栈中的特征内容时归类
编写完categories.json后,重新跑测试并把结果目录里的数据重新生成报告即可。注意categories.json是作为输入数据被读取的,修改之后需要重新执行allure generate才会生效。
5.3 高频坑:动态标题不生效、用例重复、报告中文乱码
动态标题不生效。代码里通过allure.dynamic.title()设置了标题,但报告里依然是函数名。原因是allure.title装饰器写在函数上,而dynamic.title是在运行时修改,高优先级的是动态值。如果报告里显示函数名,大概率是测试真正执行前出现了异常导致动态值没来得及写入结果文件。查这个问题的思路是看allure-results目录中的 JSON 里有没有 title 字段。
用例在报告中重复。多数情况下是因为跑了多次 pytest 命令,但没加--clean-alluredir,导致上一次的 JSON 文件仍然留在结果目录里。第二次跑批只追加不清理,报告自然出现重复用例。建议调试时先看一眼结果目录里 JSON 文件的最后修改时间。
报告中文乱码。这个问题在 Windows 下尤其常见,根源是控制台编码。pytest 输出中文时,终端会以 GBK 编码解码 UTF-8 内容,导致allure attach方法写入的文本在报告中变成乱码。解决办法并不是改 Allure 配置,而是在测试里对附件内容做编码转换:
import io text = "登录接口返回成功" result = io.StringIO(text) allure.attach(result.getvalue(), "中文内容", allure.attachment_type.TEXT)如果所有回归用例显示乱码,还可以在 pytest 的入口位置设置环境变量:
import os os.environ["PYTHONIOENCODING"] = "utf-8"这能保证 pytest 写入 Allure 结果文件时使用 UTF-8 编码,而报告模板本身强制按 UTF-8 解析。
5.4 外挂一个 JUnit 报告源,组合展示 pytest 与 Java 系统的测试结果
如果你的项目同时存在 Java 和 Python 两套测试体系,Allure 最常见的落地方式是把两类结果组合到同一份报告里。做法是让两套体系分别把结果输出到不同的目录,然后依次对两个目录执行生成命令。
allure generate ./allure-results-java -o ./allure-report --clean allure generate ./allure-results-pytest -o ./allure-report第二条命令不加--clean,Allure 就会把新数据合并进已经存在的结果里。合成功效依赖于 history 目录保留和 output 目录的累积机制。注意要用同一个allure-report目录,否则展示的不是一张全局报告。
如果一个系统在报告中存在多套相互无关联的 suite,可以在生成时通过--report-name参数给不同部分区分命名。实践中我常用这个方式区分 MVP 回归、主线冒烟测试、端到端专项这些不同属性的执行批次。
本文还有配套的精品资源,点击获取