10

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

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

我的测试用例:

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

5 回答 5

18

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

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

于 2013-09-06T09:12:12.793 回答
3

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

希望找到一种不需要铸造但尚未找到的更好方法。

于 2014-12-20T17:53:14.870 回答
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);

}
于 2017-09-06T11:50:48.157 回答
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 {

    }
于 2020-02-24T06:32:01.777 回答
-2

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

// 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
   }
}
于 2013-07-15T09:23:40.653 回答