java - 测试失败时无法从 testnglistner ontestfailure 方法中截取屏幕截图
问题描述
请在下面找到testNGlistner
. 好心检查。包pom;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.MediaEntityBuilder;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.markuputils.ExtentColor;
import com.aventstack.extentreports.markuputils.MarkupHelper;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation;
import com.aventstack.extentreports.reporter.configuration.Theme;
import generic.BaseTest;
public class testNgListners extends BaseTest implements ITestListener {
ExtentHtmlReporter htmlReporter;
ExtentReports extent;
ExtentTest logger;
@Override
public void onTestStart(ITestResult result) {
}
@Override
public void onTestSuccess(ITestResult result) {
logger = extent.createTest(result.getName());
logger.log(Status.PASS, MarkupHelper.createLabel(result.getName(), ExtentColor.GREEN));
}
@Override
public void onTestFailure(ITestResult result) {
System.out.println("hii");
logger = extent.createTest(result.getName());
logger.log(Status.FAIL, MarkupHelper.createLabel(result.getName(), ExtentColor.RED));
if (result.getStatus() == ITestResult.FAILURE) {
TakesScreenshot take = (TakesScreenshot) driver;
File srcFile = take.getScreenshotAs(OutputType.FILE);
File destFile = new File("./test-output/Sceenshots/" + result.getName() + ".png");
try {
FileUtils.copyFile(srcFile, destFile);
System.out.println("Screenshot is been taken for failed test case: " + result.getName());
logger.fail("Screenshot below" + logger.addScreenCaptureFromPath("./test-output/Sceenshots/" + result.getName() + ".png"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onTestSkipped(ITestResult result) {
//logger=extent.createTest(result.getName());
logger.log(Status.SKIP, MarkupHelper.createLabel(result.getName(), ExtentColor.ORANGE));
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {}
@Override
public void onStart(ITestContext context) {
htmlReporter = new ExtentHtmlReporter("./test-output/extent.html");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
extent.setSystemInfo("Host name", "localhost");
extent.setSystemInfo("Environment", "QA");
extent.setSystemInfo("user", "Arun K M");
htmlReporter.config().setDocumentTitle("Hybrid Automation Report");
htmlReporter.config().setReportName("Functional Testing");
htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
htmlReporter.config().setTheme(Theme.STANDARD);
}
@Override
public void onFinish(ITestContext context) {
extent.flush();
}
}
截屏时会抛出空指针异常。请帮我解决这个问题。PFB 错误详情:
java.lang.NullPointerException at pom.testNgListners.onTestFailure(testNgListners.java:53) at org.testng.internal.TestListenerHelper.runTestListeners(TestListenerHelper.java:67) at org.testng.internal.Invoker.runTestListeners(Invoker.java:第1389章)在org.testng.internal.TestMethodWorker.run(TestMethodWorker.java) :109) 在 org.testng.TestRunner.privateRun(TestRunner.java:648) 在 org.testng.TestRunner.run(TestRunner.java:505) 在 org.testng.SuiteRunner.runTest(SuiteRunner.java:455) 在 org .testng.SuiteRunner.runSequentially(SuiteRunner.java:450) 在 org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) 在 org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208) at org. testng.TestNG.runSuitesLocally(TestNG.java:1137) at org.testng.TestNG.runSuites(TestNG.java:1049) at org.testng.TestNG.run(TestNG.java:1017) at org.apache.maven.surefire .testng.TestNGExecutor.run(TestNGExecutor.java:283) 在 org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75) 在 org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider .java:120) 在 org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) 在 org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) 在 org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) 在 org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
嗨,克里希纳,
PFB 基本测试代码。
package generic;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class BaseTest implements Autoconst {
File file=new File("\\\\192.168.70.39\\IT Share\\Automation\\ERP Automation\\credential.properties");
Properties prop = new Properties();
public WebDriver driver;
@Parameters({"browser"})
@BeforeMethod
public void precondition()
{
if(browser.equals("chrome"))
{
FileInputStream fileInput =null;
try {
fileInput = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
prop.load(fileInput);
} catch (Exception e) {
e.printStackTrace();
}
System.setProperty(GECKO_KEY,GECKO_VALUE);
ChromeOptions options = new ChromeOptions();
options.setPageLoadStrategy(PageLoadStrategy.NONE);
driver=new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.get(prop.getProperty("URL"));
driver.manage().window().maximize();
}
}
@AfterMethod
public void postcondition()
{
driver.quit();
}
}
解决方案
您将 TestNG 侦听器和与 Testclass 相关的注释混合在一起,这就是导致NullPointerException
我猜你有一个也在扩展的测试类BaseTest
。为了举例,让我们将该类称为RegressionTest
.
TestNG 现在创建了两个实例:
RegressionTest
1个类实例- 1 个类实例
testNgListners
。
但是要注意的是,当testNgListners
创建实例时,根本不会调用@BeforeMethod
和@AfterMethod
注释,因为这些注释在侦听器的上下文中没有任何相关性。
要解决此问题,您需要执行以下操作:
- 重构
testNgListners
使其不会扩展BaseTest
- 现在,
BaseTest
从中移动浏览器实例化和清理逻辑。 - 您应该通过 TestNG 监听器管理您的浏览器实例化,因为一旦出现故障,您的 testng 也将使用驱动程序对象来截取屏幕截图。
修改后的侦听器如下所示:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;
public class BrowserManagementListener implements ITestListener {
private static final String BROWSER = "browser";
private File file =
new File("\\\\192.168.70.39\\IT Share\\Automation\\ERP Automation\\credential.properties");
private Properties prop = new Properties();
public static RemoteWebDriver getDriver() {
ITestResult result = Reporter.getCurrentTestResult();
if (result == null) {
throw new IllegalStateException("could not detect a valid test result");
}
Object object = result.getAttribute(BROWSER);
if (object == null) {
throw new IllegalStateException("could not find a browser");
}
return (RemoteWebDriver)object;
}
@Override
public void onTestStart(ITestResult result) {
// This line retrieves the value of
// <parameter name="browser" value="chrome"/> from your testng suite xml
String browser = result.getTestContext().getCurrentXmlTest().getParameter("browser");
if ("chrome".equalsIgnoreCase(browser)) {
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
prop.load(fileInput);
} catch (Exception e) {
e.printStackTrace();
}
}
ChromeOptions options = new ChromeOptions();
options.setPageLoadStrategy(PageLoadStrategy.NONE);
RemoteWebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
result.setAttribute(BROWSER, driver);
}
@Override
public void onTestSuccess(ITestResult result) {
cleanUpBrowser(result);
}
@Override
public void onTestFailure(ITestResult result) {
Object object = result.getAttribute(BROWSER);
if (object == null) {
return;
}
RemoteWebDriver driver = (RemoteWebDriver) object;
File srcFile = driver.getScreenshotAs(OutputType.FILE);
File destFile = new File("test-output/" + result.getName() + ".png");
try {
FileUtils.copyFile(srcFile, destFile);
System.out.println("Screenshot is been taken for failed test case: " + result.getName());
System.err.println("Screenshot below" + destFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
} finally {
cleanUpBrowser(result);
}
}
private void cleanUpBrowser(ITestResult result) {
Object driver = result.getAttribute(BROWSER);
if (driver != null) {
((RemoteWebDriver) driver).quit();
result.setAttribute(BROWSER, null);
}
}
}
这是一个测试类的样子
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(BrowserManagementListener.class)
public class SampleTestClass {
@Test
public void testMethod() {
BrowserManagementListener.getDriver().get("http://www.google.com");
throw new RuntimeException("Simulating an error");
}
}
推荐阅读
- c++ - 使用 `{}` 在 C++ 中聚合初始化联合
- javascript - Javascript中的未定义与引用错误
- reactjs - WebStorm 特定文件名不会被识别为 TypeScript 文件
- python-3.x - 为什么 pip 要求我选择一个程序来运行 pip?
- java - android中更改主题的切换按钮
- tensorflow - Tensorflow 1.12 与 Tensorflow 2.4 不同的结果
- macos - 如何修改 vim .zshrc 中的文本?
- c# - Azure FileShare - FileShareClient.UploadAsync(stream) - 找不到资源错误
- python - 与 Html 中的日期类型匹配的 Python 类型
- powershell - 需要将变量作为字符串存储在另一个变量中