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

Posted

技术标签:

【中文标题】TestNG 中的非静态驱动程序和屏幕截图侦听器【英文标题】:Non Static driver and screenshot listener in TestNG 【发布时间】: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
    

【问题讨论】:

【参考方案1】:

您不必在测试中传递驱动程序或调用 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.
        

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

【讨论】:

谢谢老兄!唯一不同的是,您选择类型转换为基类并使用带有文本上下文的 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
   

【讨论】:

以上是关于TestNG 中的非静态驱动程序和屏幕截图侦听器的主要内容,如果未能解决你的问题,请参考以下文章

将 TestNG 屏幕截图输出到 Jenkins

将屏幕截图附加到 TestNG 失败的方法结果

如何在 testNG 报告中包含失败屏幕截图

如何使用 Java 截屏自动化测试? [关闭]

电脑怎么全屏截图

屏幕截图