简体   繁体   English

当测试失败时,无法从testnglistner ontestfailure方法获取屏幕截图

[英]can't able to take screenshot from testnglistner ontestfailure method when ever the test fails

Please find below the complete code for testNGlistner . 请在下面找到testNGlistner的完整代码。 Kindly check. 好心检查。 package 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();
    }
}

while taking a screenshot it throws null pointer exception. 截取屏幕截图时会抛出空指针异常。 Kindly help me to resolve this. 请帮我解决这个问题。 PFB the error details: 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) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1042) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java:505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at 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) a org.testng.internal.Invoker.runTestListeners上的org.testng.internal.TestListenerHelper.runTestListeners(TestListenerHelper.java:67)中的pom.testNgListners.onTestFailure(testNgListners.java:53)中的java.lang.NullPointerException(Invoker.java: 1389)org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1042)org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java) :109)org.testng.TestRunner.privateRun(TestRunner.java:648)org.testng.TestRunner.run(TestRunner.java:505)atg.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)atg.testng.SuiteRunnerWorker。 runSuite(SuiteRunnerWorker.java:52)org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)a t 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) at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75) at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:120) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418) 在Org.apache的org.testng.TestNG.run(TestNG.java:1017)的org.testng.TestNG.runSuites(TestNG.java:1049)上的t org.testng.TestNG.runSuitesLocally(TestNG.java:1137)。 maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:283)位于org.apache.maven.surefire.test.TestNGProvider的org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75)。在org.apache.maven.surefire.boot.Fork.上一个org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)调用(TestNGProvider.java:120)(ForkedBooter.java:345) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)

Hi Krishna, 嗨克里希纳,

PFB the basetest code. 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();
    }

}

You have mixed up TestNG listeners and Testclass related annotations together and that is what is causing the NullPointerException 您已将TestNG侦听器和Testclass相关注释混合在一起,这就是导致NullPointerException

I am guessing you have a test class which is also extending BaseTest . 我猜你有一个测试类,它也在扩展BaseTest For the sake of example let's call that class as RegressionTest . 为了举例,我们将该类称为RegressionTest

TestNG now creates two instances : TestNG现在创建两个实例:

  • 1 instance for RegressionTest class RegressionTest类的1个实例
  • 1 instance for testNgListners class. testNgListners类的1个实例。

But the catch is that when the testNgListners instance is created, the @BeforeMethod and @AfterMethod annotations are not invoked at all, because these annotations don't have any relevance in the context of a listener. 但问题是,当创建testNgListners实例时, testNgListners不会调用@BeforeMethod@AfterMethod注释,因为这些注释在侦听器的上下文中没有任何相关性。

To fix this, you need to do the following: 要解决此问题,您需要执行以下操作:

  • Refactor testNgListners so that it does not extend BaseTest 重构testNgListners ,使其不扩展BaseTest
  • Now within BaseTest move the browser instantiation and cleanup logic from it. 现在,在BaseTest移动浏览器实例化和清理逻辑。
  • You should manage your browser instantiation via a TestNG listener, because the driver object is also going to be used by your testng to take screenshots whenever there is a failure. 您应该通过TestNG侦听器管理浏览器实例化,因为每当发生故障时,您的testng也会使用驱动程序对象来截取屏幕截图。

Here's how the modified listener would look like: 以下是修改后的侦听器的外观:

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);
    }
  }
}

And here's how a test class would look like 以下是测试类的外观

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");
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用onTestFailure与TestNG一起使用ScreenShot - Unable to take ScreenShot with TestNG using onTestFailure 无法拍摄布局的屏幕截图 - can't take screenshot of a layout Selenium 可以在 JUnit 测试失败时截取屏幕截图吗? - Can Selenium take a screenshot on test failure with JUnit? 显示“无法保存截图”时是否可以截屏? - Is it possible to take a screenshot when it show " Couldn't save screenshot"? Robotium-如何获取屏幕截图并从测试用例内部打开 - Robotium - How to take a screenshot and open from inside the test case 有没有办法,我可以获取在 testNG 中运行的当前测试方法的名称,如果测试失败(在不同的类中)以截图的名称使用它 - Is there a way, I can fetch the name of current test method running in testNG and use it in the name of screenshot if test fails( in different class) Selenium可以对测试(Assert.assertEquals())失败进行截图吗? - Can Selenium take a screenshot on test(Assert.assertEquals()) failure? 如何将错误消息从导致异常的方法传递给侦听器中的onTestFailure方法 - How to pass error message from method causing exception to onTestFailure method in Listener 截取Selenium中测试失败的屏幕截图 - Take screenshot on test failure in Selenium 为什么我不能在Java中使用Selenium Webdriver截屏? - Why I can't take a screenshot using selenium webdriver in java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM