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

时间:2013-07-12 00:33:29

标签: java selenium selenium-webdriver testng

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

有没有办法全局访问屏幕截图监听器中的非静态驱动程序?

我的测试用例:

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

5 个答案:

答案 0 :(得分:12)

你不必在测试中传递驱动程序或调用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. 在您的侦听器中,您需要访问基类;

  3. public class 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.
            }
    }
    

    您的测试现在还没有意识到屏幕碎片甚至被捕获,并且可以通过添加监听器来控制。

答案 1 :(得分:0)

我打算去寻找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...

希望有一种更好的方法,不需要施法,但却找不到。

答案 2 :(得分:0)

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

}

答案 3 :(得分:0)

您也可以在没有侦听器的情况下执行此操作。在您的基础测试类中,将以下代码添加到@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 {

    }

答案 4 :(得分:-1)

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

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