如何将Allure报告中的重试实例拆分为独立测试用例?
我们项目通过系统属性传递变量触发测试运行,示例代码:
public static String USER = System.getProperty("user", "ADMIN_HQ");
通过这种方式可按需指定用户、浏览器、服务器等参数,直接调用公共字符串即可,无需向测试方法传递参数。
当前遇到的Allure报告问题:
用bash脚本两次运行同一测试方法,分别指定ADMIN_1和ADMIN_2:
#!/bin/bash mvn -Dtest=ScreenshotComparisonTests#salesForecastComparison -Duser=ADMIN_1 -Dbrowser=CHROME_HEADLESS test mvn -Dtest=ScreenshotComparisonTests#salesForecastComparison -Duser=ADMIN_2 -Dbrowser=CHROME_HEADLESS test allure serve target/allure-results
但Allure将两次运行归为重试实例,导致若ADMIN_1运行失败、ADMIN_2成功,无法直观看到失败结果(需进入重试标签页查看),图表和整体统计失效,也无法按用户名分组(比如为每个用户创建Story)。
已尝试的方案:
- 设置Epics、Stories、Features、parentSuite、Suite、subsuite等标签
- 每次测试前添加Allure参数:
//Add Allure parameters Allure.parameter("Browser", browserVersion); Allure.parameter("OS Info", osInfo); Allure.parameter("Server", serverName); Allure.parameter("Build Version", version); Allure.parameter("Logged in as", USER); Allure.parameter("Machine username", machineUsername);
这些参数每次运行均不同,但报告仍将两次运行归为同一测试用例;也查看过container.json和result.json文件,未找到有效解决方向。
核心思路是让Allure识别不同参数的测试运行具有唯一性,打破默认用「测试类+方法名」作为唯一标识的规则,以下是几种可行方案:
1. 动态生成测试名称(加入唯一参数)
在测试方法中,通过Allure生命周期API动态修改测试名称,将USER等关键参数加入名称:
import io.qameta.allure.Allure; import org.junit.jupiter.api.Test; @Test public void salesForecastComparison() { // 动态设置带用户标识的测试名称 Allure.getLifecycle().updateTestCase(testCase -> testCase.setName("销售预测对比 - 用户: " + USER) ); // 测试逻辑代码 }
修改后,两次运行的测试名称不同,Allure会将它们识别为独立用例。
2. 自定义测试UUID(基于参数组合)
Allure通过UUID识别测试实例的唯一性,可基于参数组合生成唯一UUID,确保每次运行的UUID不同:
import io.qameta.allure.Allure; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; @BeforeEach public void setup() { // 用USER和browser参数生成唯一标识 String uniqueKey = USER + "_" + System.getProperty("browser"); UUID testUuid = UUID.nameUUIDFromBytes(uniqueKey.getBytes()); Allure.getLifecycle().updateTestCase(testCase -> testCase.setUuid(testUuid.toString()) ); }
在@BeforeEach方法中执行这段代码,每个测试实例的UUID会基于参数动态生成,避免被判定为重试。
3. 脚本层面分开存储Allure结果
每次测试运行指定独立的Allure结果目录,最后合并生成报告:
#!/bin/bash # 第一次运行,结果存到独立目录 mvn -Dtest=ScreenshotComparisonTests#salesForecastComparison -Duser=ADMIN_1 -Dbrowser=CHROME_HEADLESS -Dallure.results.directory=target/allure-results-admin1 test # 第二次运行,结果存到另一独立目录 mvn -Dtest=ScreenshotComparisonTests#salesForecastComparison -Duser=ADMIN_2 -Dbrowser=CHROME_HEADLESS -Dallure.results.directory=target/allure-results-admin2 test # 合并结果到统一目录 mkdir -p target/allure-results cp -r target/allure-results-admin1/* target/allure-results/ cp -r target/allure-results-admin2/* target/allure-results/ # 启动Allure报告 allure serve target/allure-results
这种方式从存储层面隔离两次运行的结果,Allure生成报告时会自动识别为独立用例。
4. 使用参数化测试(推荐方案)
如果使用JUnit 5,直接通过@ParameterizedTest实现参数化,Allure会自动为每个参数实例生成独立用例:
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import io.qameta.allure.Allure; @ParameterizedTest @ValueSource(strings = {"ADMIN_1", "ADMIN_2"}) public void salesForecastComparison(String user) { Allure.parameter("Logged in as", user); // 测试逻辑代码,直接使用参数user }
也可通过@CsvSource、@MethodSource读取外部参数,这种方案最规范,天然支持按参数分组和统计。
Allure判定重试的核心是测试用例的UUID和测试名称/路径,只要让不同参数的测试实例拥有不同的UUID或名称,就能被识别为独立用例。参数化测试是从根源解决这类问题的最佳实践。
内容的提问来源于stack exchange,提问作者Hazel Egan

