如何等待cucumber.json与cucumber.html生成并写入内容后执行操作?
解决Cucumber报告文件复制时为空的问题
问题根源
Cucumber的json、html报告文件往往是异步写入的,你在@AfterAll钩子中执行复制时,报告可能还在后台写入过程中,所以复制到的是未写完的空文件。
可行解决方案
1. 用Cucumber事件监听器替代@AfterAll
直接监听Cucumber测试运行结束的事件,在报告完全生成后再执行复制,这是最可靠的方式:
public class ReportCopyListener implements EventListener { @Override public void setEventPublisher(EventPublisher publisher) { // 监听测试运行完成的事件 publisher.registerHandlerFor(TestRunFinished.class, this::handleTestFinish); } private void handleTestFinish(TestRunFinished event) { // 这里执行文件复制逻辑,此时报告已100%生成完毕 copyReportFiles(); } private void copyReportFiles() { // 实现文件复制逻辑,比如用Apache Commons IO或JDK的Files类 File jsonSrc = new File("target/cucumber.json"); File htmlSrc = new File("target/cucumber.html"); String destDir = "reports/" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); new File(destDir).mkdirs(); try { FileUtils.copyFile(jsonSrc, new File(destDir + "/cucumber.json")); FileUtils.copyFile(htmlSrc, new File(destDir + "/cucumber.html")); } catch (IOException e) { e.printStackTrace(); } } }
然后在Cucumber配置里注册这个监听器:
@CucumberOptions( plugin = {"com.yourpackage.ReportCopyListener", "json:target/cucumber.json", "html:target/cucumber.html"} )
2. 给@AfterAll加文件写入等待逻辑
如果一定要用@AfterAll,可以通过轮询文件大小的方式,确认文件不再变化后再复制:
@AfterAll public static void copyReports() throws InterruptedException { File jsonFile = new File("target/cucumber.json"); File htmlFile = new File("target/cucumber.html"); // 等待两个文件都写完 waitForFileStable(jsonFile); waitForFileStable(htmlFile); // 执行复制操作 String destDir = "reports/" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); new File(destDir).mkdirs(); try { Files.copy(jsonFile.toPath(), new File(destDir + "/cucumber.json").toPath(), StandardCopyOption.REPLACE_EXISTING); Files.copy(htmlFile.toPath(), new File(destDir + "/cucumber.html").toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } } private static void waitForFileStable(File file) throws InterruptedException { long lastSize = -1; int waitCount = 0; // 最多等待10秒(每次间隔500ms) while (waitCount < 20) { long currentSize = file.length(); // 文件大小大于0且两次检查无变化,说明写入完成 if (currentSize > 0 && currentSize == lastSize) { break; } lastSize = currentSize; Thread.sleep(500); waitCount++; } }
3. 检查报告插件的同步性
如果用的是第三方报告插件,确认其是否支持同步生成报告。比如官方的cucumber-html插件是同步写入的,若用了其他异步插件,建议替换为官方版本,避免后台写入导致的问题。
内容的提问来源于stack exchange,提问作者Sai kumar Sappa
相关产品推荐
相关产品推荐

