【问题标题】:Non Static driver and screenshot listener in TestNGTestNG 中的非静态驱动程序和屏幕截图侦听器
【发布时间】:2013-07-10 10:58:21
【问题描述】:

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

有没有办法在截图监听器中全局访问非静态驱动?

我的测试用例:

@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
    }
}

【问题讨论】:

    标签: java selenium selenium-webdriver testng


    【解决方案1】:

    您不必在测试中传递驱动程序或调用 testfailure(实际上这会破坏测试侦听器的意义);

    以下将在监听器中实现截图,无需传递驱动;

    1. 所有测试类都必须扩展一个简单的基础测试类;

      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);
                      }
      
              }
          }
      
    2. 在你的监听器中,你需要访问基类;

    公共类 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.
            }
    }
    

    您的测试现在不知道屏幕截图甚至被捕获,并且可以通过添加侦听器来控制。

    【讨论】:

    • 谢谢老兄!唯一不同的是,您选择类型转换为基类并使用带有文本上下文的 Guide Inject lib 是,您的选项适用于并行执行,而其他选项则不适用。再次感谢!
    • 这对我也很有帮助,我花了几天的时间来摆脱这个 NPE。
    【解决方案2】:

    我打算采用 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...
    

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

    【讨论】:

      【解决方案3】:

      如果您想在项目中的任何地方访问驱动程序,请在浏览器设置类中定义 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);
      
      }
      

      【讨论】:

        【解决方案4】:

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

        @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 {
        
            }
        

        【讨论】:

          【解决方案5】:

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

          // 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
             }
          }
          

          【讨论】:

            猜你喜欢
            • 2019-07-01
            • 2018-06-20
            • 1970-01-01
            • 2021-04-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-12
            相关资源
            最近更新 更多