ExtentReport的@AfterMethod块触发NullPointerException问题求助
解决ExtentReport @AfterMethod中的NullPointerException问题
你的空指针异常根源非常明确:logger对象从未被初始化。你在类中声明了public ExtentTest logger;,但全程没有通过extent.startTest()为它创建实例,导致在@AfterMethod里调用logger.log()时,logger仍为null,直接触发了空指针异常。
修复步骤
- 在每个
@Test方法的开头,调用extent.startTest()初始化logger,传入当前测试方法的名称,让日志和测试用例关联起来; - 确保
@AfterMethod中使用的logger是已完成初始化的实例。
修改后的完整代码
package com.cna.qa.testcases; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.relevantcodes.extentreports.ExtentReports; import com.relevantcodes.extentreports.ExtentTest; import com.relevantcodes.extentreports.LogStatus; import junit.framework.Assert; public class VerifyTitle { public ExtentReports extent; public ExtentTest logger; public WebDriver driver; @BeforeTest public void beforetest() { extent = new ExtentReports("C:\\Users\\mm\\selenium_projects\\SmokeTest\\output\\extentReport.html", true); } @Test public void verifyBlogTitle1() { // 初始化logger,绑定当前测试用例 logger = extent.startTest("verifyBlogTitle1"); System.setProperty("webdriver.gecko.driver", "C:\\Users\\mmia\\IdeaProjects\\geckoDriver\\geckodriver.exe"); driver = new FirefoxDriver(); driver.manage().window().maximize(); driver.get("https://devxx.yyy.net"); String title = driver.getTitle(); Assert.assertTrue(title.contains("Dashboard")); // 可选:在测试过程中添加步骤日志 logger.log(LogStatus.INFO, "已导航至目标URL并验证页面标题"); } public static String screenshot(WebDriver driver, String screenshotname) throws IOException { String dtname = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()); TakesScreenshot ts = (TakesScreenshot) driver; File source = ts.getScreenshotAs(OutputType.FILE); String destination = System.getProperty("user.dir") + "\\screenshots\\" + screenshotname + "_" + dtname + ".png"; File finalDestination = new File(destination); FileUtils.copyFile(source, finalDestination); return destination; } @AfterMethod() public void teardown(ITestResult result) throws IOException { if (result.getStatus() == ITestResult.SUCCESS) { System.out.println(result.getStatus()); logger.log(LogStatus.PASS, result.getName() + " 执行通过"); } else if (result.getStatus() == ITestResult.FAILURE) { logger.log(LogStatus.FAIL, "失败测试用例名称:" + result.getName()); logger.log(LogStatus.FAIL, "失败原因:" + result.getThrowable()); String screenshotPath = VerifyTitle.screenshot(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); driver.quit(); } @AfterTest public void aftertest() { extent.flush(); extent.close(); } }
额外提示
- 如果后续新增多个
@Test方法,每个方法都需要在开头初始化logger,保证每个测试用例都有独立的日志实例; - 我调整了失败用例的截图日志写法,原来的写法只会在报告中显示路径字符串,改用
addScreenCapture()可以让报告直接嵌入截图,更直观。
内容的提问来源于stack exchange,提问作者Sharif Mia
相关产品推荐
相关产品推荐

