Java TestNG中的非静态驱动程序和屏幕截图侦听器
我有一个将驱动程序作为非静态变量调用的测试用例。我还在测试用例中添加了截图侦听器。当测试用例失败时,控件将自动发送到屏幕截图侦听器。。。但是,由于我的驱动程序是一个非静态变量,因此无法在屏幕截图侦听器中访问它。所以我得到了null指针异常 是否有办法全局访问屏幕截图侦听器中的非静态驱动程序 我的测试用例: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
@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);
}
}
}
@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 {
}