Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TestNG中的非静态驱动程序和屏幕截图侦听器_Java_Selenium_Selenium Webdriver_Testng - Fatal编程技术网

Java TestNG中的非静态驱动程序和屏幕截图侦听器

Java TestNG中的非静态驱动程序和屏幕截图侦听器,java,selenium,selenium-webdriver,testng,Java,Selenium,Selenium Webdriver,Testng,我有一个将驱动程序作为非静态变量调用的测试用例。我还在测试用例中添加了截图侦听器。当测试用例失败时,控件将自动发送到屏幕截图侦听器。。。但是,由于我的驱动程序是一个非静态变量,因此无法在屏幕截图侦听器中访问它。所以我得到了null指针异常 是否有办法全局访问屏幕截图侦听器中的非静态驱动程序 我的测试用例: @Test public void testCase() { //non-static driver is initialized } 我的截图听众: public class S

我有一个将驱动程序作为非静态变量调用的测试用例。我还在测试用例中添加了截图侦听器。当测试用例失败时,控件将自动发送到屏幕截图侦听器。。。但是,由于我的驱动程序是一个非静态变量,因此无法在屏幕截图侦听器中访问它。所以我得到了null指针异常

是否有办法全局访问屏幕截图侦听器中的非静态驱动程序

我的测试用例:

@Test
public void testCase() {
     //non-static driver is initialized
}
我的截图听众:

public class ScreenshotListener extends TestListenerAdapter
{
    @Override
    public void onTestFailure(ITestResult testResult) {
        //driver needs to be accessed here
    }
}

如果您知道在任何地方访问驱动程序意味着什么,那么在执行流程中,您必须将驱动程序引用作为参数传递到任何地方

// i assume onTestFailure method has been called explicitly.

@Test
public void testCase() 
{
  Webdriver driver=XXXXDriver();
  try
  {
       // your tests
  }
  catch(Exception e)
  {
      onTestFailure(new ITestResult (),driver)
  }

public class ScreenshotListener extends TestListenerAdapter
{

   @Override
   public void onTestFailure(ITestResult testResult,Webdriver driver) 
   {
      // you can access your driver here
   }
}

您不必在测试中传递驱动程序或调用testfailure(事实上,这违背了测试侦听器的观点)

以下内容将在听众中实现屏幕截图,而无需让驾驶员四处走动

  • 所有测试类必须扩展一个简单的基本测试类

    public asbtract baseTestCase() {
    
        private WebDriver driver;
    
        public WebDriver getDriver() {
                return driver;
    }
    
        @BeforeMethod
        public void createDriver() {
                Webdriver driver=XXXXDriver();
        }
    
        @AfterMethod
            public void tearDownDriver() {
            if (driver != null)
            {
                    try
                    {
                        driver.quit();
                    }
                    catch (WebDriverException e) {
                        System.out.println("***** CAUGHT EXCEPTION IN DRIVER TEARDOWN *****");
                        System.out.println(e);
                    }
    
            }
        }
    
  • 在侦听器中,您需要访问基类

  • 公共类ScreenshotListener扩展TestListenerAdapter{

    @Override
    public void onTestFailure(ITestResult result)
    {
            Object currentClass = result.getInstance();
            WebDriver webDriver = ((BaseTest) currentClass).getDriver();
    
            if (webDriver != null)
            {
    
               File f = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
    
               //etc.
            }
    }
    

    您的测试现在还不知道ScreenshGet甚至正在被捕获,并且可以通过添加侦听器来控制它。

    我本来打算使用Robbie提供的解决方案,但希望避免占用我的基类。当我使用Guice注入我的WebDriver提供程序时,我选择通过挂接通过TestNG属性传递实例它在设置测试类中启动一次,如下所示:

    public class Setup {
        @Inject WebDriver driver;
    
        @BeforeSuite
        public void onStart(ITestContext testContext) {
            testContext.setAttribute("WebDriver", this.driver);
        }
    }
    
    然后在我的听众中,我简单地把它拉出来:

    @Override
    public void onTestFailure(ITestResult result) {
    
        Object webDriverAttribute = 
            result.getTestContext().getAttribute("WebDriver");
        // test, cast, and use...
    

    希望找到一种不需要强制转换但尚未找到的更好方法。

    如果您想在项目中的任何地方访问驱动程序,请在浏览器设置类中定义wedDriver,如下所示

    public class BrowserSetup{
    private WebDriver driver;
    public WebDriver getDriver() 
    {
        return driver;
    }
         use rest of code 
    }
    
    并在testng侦听器中使用以下代码

    public class TestNgListener extends BrowserSetup implements ITestListener, ISuiteListener, IInvokedMethodListener{
    WebDriver driver =null;
    
    @Override
    public void onTestFailure(ITestResult arg0) {
        Object currentClass = arg0.getInstance();
        WebDriver driver = ((BrowserSetup) currentClass).getDriver();
        //this.driver = ((BrowserSetup)currentClass).getDriver;
    
        // This is calling the printTestResults method
        try {
            getScreenshot(arg0.getTestName(), driver);
            System.out.println("Screenshot taken");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("Exception while takescreenshot "+e.getMessage());
            //e.printStackTrace();
        }
        printTestResults(arg0);
    
    }
    

    您也可以在没有侦听器的情况下执行此操作。在基本测试类中,在@afterTest中添加以下代码(或根据您的要求添加任何@afterXXXX注释)


    谢谢你,伙计!唯一的区别是,你选择的类型转换到基类和使用带有文本上下文的Guide Inject lib,你的选择适用于并行执行,而其他人不适用。再次感谢!这也确实帮助了我,我花了几天的时间来摆脱这个NPE。
    @AfterMethod
    public void afterMethod(ITestResult result){
        try {
            if (result.getStatus() == ITestResult.FAILURE) {
                //add your screenshot logic here.
            } else if (result.getStatus() == ITestResult.SKIP) {
    
            } else if (result.getStatus() == ITestResult.SUCCESS){
    
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
    
        }