You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium TakesScreenshot生成损坏图片,Cucumber报告异常求助

解决Cucumber报告中截图偶尔损坏的建议

针对你遇到的截图损坏导致报告无内容的问题,可尝试以下几种方案:

1. 增加截图重试机制

偶尔截图失败可能是浏览器渲染未完成或WebDriver临时响应异常,通过重试可以降低概率:

private void takeScreenshotIfScenarioFailed() {
    if (Context.scenario.isFailed()) {
        byte[] screenshot = null;
        int retryCount = 3; // 重试3次
        while (retryCount > 0 && screenshot == null) {
            try {
                screenshot = ((TakesScreenshot) Context.driver).getScreenshotAs(OutputType.BYTES);
                // 简单验证字节数组有效性
                if (screenshot.length < 100) { // 有效PNG至少有几百字节
                    screenshot = null;
                    retryCount--;
                    Thread.sleep(500); // 间隔500ms重试
                }
            } catch (Exception e) {
                retryCount--;
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                }
            }
        }
        if (screenshot != null) {
            Context.scenario.attach(screenshot, "image/png", "screenshot");
        }
    }
}

2. 验证截图字节的有效性

在attach之前先验证字节数组是否为有效PNG,避免损坏的图片嵌入报告:

private boolean isPngValid(byte[] data) {
    if (data == null || data.length < 8) {
        return false;
    }
    // PNG文件头固定为8字节:89 50 4E 47 0D 0A 1A 0A
    byte[] pngHeader = {(byte)0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
    for (int i = 0; i < pngHeader.length; i++) {
        if (data[i] != pngHeader[i]) {
            return false;
        }
    }
    return true;
}

// 在截图方法中调用
private void takeScreenshotIfScenarioFailed() {
    if (Context.scenario.isFailed()) {
        try {
            byte[] screenshot = ((TakesScreenshot) Context.driver).getScreenshotAs(OutputType.BYTES);
            if (isPngValid(screenshot)) {
                Context.scenario.attach(screenshot, "image/png", "screenshot");
            }
        } catch (Exception e) {
            // 记录日志,避免影响测试流程
            e.printStackTrace();
        }
    }
}

3. 延迟截图

场景失败后,页面可能仍处于加载或状态变化中,延迟几秒再截图:

private void takeScreenshotIfScenarioFailed() {
    if (Context.scenario.isFailed()) {
        try {
            Thread.sleep(1000); // 延迟1秒,可根据实际调整
            byte[] screenshot = ((TakesScreenshot) Context.driver).getScreenshotAs(OutputType.BYTES);
            Context.scenario.attach(screenshot, "image/png", "screenshot");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. 改用临时文件中转截图

避免直接通过OutputType.BYTES获取可能的异常,先保存为临时文件再读取字节:

private void takeScreenshotIfScenarioFailed() {
    if (Context.scenario.isFailed()) {
        try {
            File tempFile = ((TakesScreenshot) Context.driver).getScreenshotAs(OutputType.FILE);
            byte[] screenshot = Files.readAllBytes(tempFile.toPath());
            if (isPngValid(screenshot)) {
                Context.scenario.attach(screenshot, "image/png", "screenshot");
            }
            // 删除临时文件
            tempFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. 确保WebDriver未提前关闭

检查测试代码中是否存在场景失败后提前关闭driver的逻辑,确保截图时driver仍处于活跃状态。比如在After钩子中,先执行截图再关闭driver:

@After
public void tearDown() {
    takeScreenshotIfScenarioFailed();
    // 之后再关闭driver
    if (Context.driver != null) {
        Context.driver.quit();
    }
}

内容的提问来源于stack exchange,提问作者Said

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:22:45