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

ExtentReports无法嵌入截图至报告,求Selenium+TestNG代码修改方案

问题:ExtentReports无法嵌入失败测试用例截图的解决方法

我正在使用Selenium WebDriver、Maven和TestNG编写测试代码,尝试捕获失败测试用例的截图。目前截图已在项目中生成,但无法嵌入到ExtentReports报告中,请问需要修改代码中的哪些部分?

我的测试代码如下:

WebDriver driver;
ExtentReports extent;
ExtentTest logger;

@BeforeTest
public void setUp() {
    extent = new ExtentReports("C:\\Users\\IdeaProjects\\p\\test-output\\report.html", true);
    extent.loadConfig(new File("C:\\Users\\IdeaProjects\\p\\test-output\\extent-config.xml"));
    driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    driver.get("http://www.google.com");
}

@Test
public void testExtentReports() {
    logger = extent.startTest("testExtentReports");
    Assert.assertTrue(false);
}

@AfterMethod
public void tearDown(ITestResult result) throws IOException {
    if(result.getStatus() == ITestResult.FAILURE) {
        logger.log(LogStatus.FAIL, "测试用例失败:"+result.getName());
        logger.log(LogStatus.FAIL, "失败原因:"+result.getThrowable());
        String screenshotPath = TestMine.getScreenshot(driver, result.getName());
        logger.log(LogStatus.FAIL, logger.addScreenCapture(screenshotPath));
    } else if(result.getStatus() == ITestResult.SKIP) {
        logger.log(LogStatus.SKIP, "测试用例跳过:"+result.getName());
    }
    extent.endTest(logger);
}

public static String getScreenshot(WebDriver driver, String screenshotName) throws IOException {
    String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
    TakesScreenshot ts = (TakesScreenshot) driver;
    File source = ts.getScreenshotAs(OutputType.FILE);
    // 执行后会在src下生成"FailedTestsScreenshots"文件夹
    String destination = "ss/" + screenshotName+dateName+".png";
    File finalDestination = new File(destination);
    FileUtils.copyFile(source, finalDestination);
    return destination;
}

@AfterTest
public void endReport() {
    extent.flush();
    extent.close();
    driver.quit();
}

核心问题与修改方案

1. 修复截图日志的调用逻辑

原代码中logger.log(LogStatus.FAIL, logger.addScreenCapture(screenshotPath));的写法错误,addScreenCapture返回的是媒体对象,不需要嵌套调用,应该直接将其作为日志内容的参数传入。

修改为:

// 规范写法:将截图媒体对象作为日志的附加内容
logger.log(LogStatus.FAIL, "失败截图:", logger.addScreenCapture(screenshotPath));
// 若使用ExtentReports 3.x+版本,推荐用MediaEntityBuilder方式
logger.fail("失败截图:", MediaEntityBuilder.createScreenCaptureFromPath(screenshotPath).build());

2. 确保截图路径可被报告访问

当前截图保存在项目根目录的ss/文件夹,而报告生成在test-output目录下,报告无法跨目录读取截图文件。需要调整截图保存路径到报告所在的目录下:

修改getScreenshot方法中的路径:

public static String getScreenshot(WebDriver driver, String screenshotName) throws IOException {
    String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
    TakesScreenshot ts = (TakesScreenshot) driver;
    File source = ts.getScreenshotAs(OutputType.FILE);
    // 将截图保存到report.html所在的test-output/ss目录下
    String destDir = System.getProperty("user.dir") + "/test-output/ss";
    // 确保文件夹存在,避免创建文件失败
    new File(destDir).mkdirs();
    String destination = destDir + "/" + screenshotName + dateName + ".png";
    File finalDestination = new File(destination);
    FileUtils.copyFile(source, finalDestination);
    // 返回相对报告的路径,或直接返回绝对路径
    return destination;
}

3. (可选)替换硬编码路径为动态路径

为了适配不同环境,将初始化报告的硬编码路径改为动态获取项目根目录:

@BeforeTest
public void setUp() {
    String projectPath = System.getProperty("user.dir");
    extent = new ExtentReports(projectPath + "/test-output/report.html", true);
    extent.loadConfig(new File(projectPath + "/test-output/extent-config.xml"));
    // ... 其他初始化代码
}

修改后的关键代码片段

@AfterMethod
public void tearDown(ITestResult result) throws IOException {
    if(result.getStatus() == ITestResult.FAILURE) {
        logger.log(LogStatus.FAIL, "测试用例失败:"+result.getName());
        logger.log(LogStatus.FAIL, "失败原因:"+result.getThrowable());
        String screenshotPath = TestMine.getScreenshot(driver, result.getName());
        // 使用规范方式添加截图
        logger.fail("失败截图:", MediaEntityBuilder.createScreenCaptureFromPath(screenshotPath).build());
    } else if(result.getStatus() == ITestResult.SKIP) {
        logger.log(LogStatus.SKIP, "测试用例跳过:"+result.getName());
    }
    extent.endTest(logger);
}

public static String getScreenshot(WebDriver driver, String screenshotName) throws IOException {
    String dateName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
    TakesScreenshot ts = (TakesScreenshot) driver;
    File source = ts.getScreenshotAs(OutputType.FILE);
    String destDir = System.getProperty("user.dir") + "/test-output/ss";
    new File(destDir).mkdirs();
    String destination = destDir + "/" + screenshotName + dateName + ".png";
    File finalDestination = new File(destination);
    FileUtils.copyFile(source, finalDestination);
    return destination;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:50:22