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
相关产品推荐
相关产品推荐

