使用TestNG + Java + PageFactory在使用@FindBy初始化WebElements时出现NullPointerException

时间:2016-04-27 16:35:18

标签: oop inheritance selenium-webdriver testng

我试图在Chrome中运行我的测试。到目前为止我一直在使用Firefox,而且使用FF一切都运行良好。但现在我需要切换到Chrome,我遇到了启动ChromeDriver的问题。

我想我的框架架构有问题或者缺少对TestNG的理解。我使用堆栈TestNG + WebDriver + PageObject + Java

类结构如下所示:classes structure

ConciseAPI - 是一个抽象类,意味着一旦其子类尝试从ConciseAPI访问辅助方法,就会创建其对象。在简洁的API中,我们以这种方式使用驱动程序实例:

public abstract WebDriver getWebDriver();

如您所见,方法本身并未被描述。 BaseTest扩展了ConciseAPI,BaseTest是一个创建和存在WebDriver实例的类。所有子类都继承WebDriver实例并通过以下方法访问它:

@Override
public WebDriver getWebDriver() {
    return driver;
}

BasePage.class扩展了ConciseAPI并使用上面提到的完全相同的@Override方法访问驱动程序实例。

它将webdriver实例存储在私有对象中。当然,它具有由所有子页面类继承的PageFactory方法:

private WebDriver driver;
public BasePage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(driver, this);
}

现在,到BaseTest.class,创建webdriver实例。当我使用FirefoxDriver运行测试时,这就是它的样子。一切正常100%:

public class BaseTest extends ConciseAPI {
// ConciseAPI is a public abstract class with basic helper methods, waits and assertions

public static FirefoxDriver driver = new FirefoxDriver();

@BeforeSuite
public void setUp() {
    openPage("http://url");

    // makes sure page is ready for interactions
    elementIsPresent(someElement);
}

//used to make it possible to get WebDriver instance in different classes
@Override
public WebDriver getWebDriver() {
    return driver;
}

@AfterSuite
public void tearDown() {
    driver.quit();
}

当我尝试启动ChromeDriver时,这就是我的BaseTest课程的样子。

public class BaseTest extends ConciseAPI {

private static String driverPath = "path/to/chromedriver";
public static ChromeDriver driver;

@BeforeSuite
public void setUpEnvironment() {
    System.setProperty("webdriver.chrome.driver", driverPath);
    driver = new ChromeDriver();
    openPage("http://url");

    // makes sure page is ready for interactions
    elementIsPresent(someElement);

}

//if needed, in TestClasses I use getWebdriver.someMethod() instead of driver.someMethod()
@Override
public WebDriver getWebDriver() {
    return driver;
}

@AfterSuite
public void tearDown() {
    driver.quit();
}

似乎创建了WebDriver实例(浏览器出现在屏幕上),并且可以通过打开url并最大化浏览器窗口的openPage()方法访问它。当测试进行到一个以WebElement作为参数的方法(应该在BasePage.class中定义)时,我得到NullPointerException。

这是一个堆栈跟踪:

java.lang.NullPointerException
at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38) <1 internal call>

at packagename.base.ConciseAPI.elementIsPresent(ConciseAPI.java:58)
// in this class a method is invoked that is accessed from the class below \/\/\/

at packagename.test1.RegularAccLoginTest.logInTest(RegularAccLoginTest.java:19) <16 internal calls>
// error in this class refers to a method accessed from ConciseAPI
// Method has WebElement as an argument
// WebElement is supposed to be found by @FindBy in a BasePage.class, but somehow it doesn't.
// ^^^ structure description at the beginning of the post shows BasePage.class code.

at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) <3 Internal calls>
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:121) <5 internal calls>

当我尝试使用ChromeDriver启动测试时,我在BaseTest.class中做错了什么?我不会说问题出现在BasePage.class中(即使它看起来像是这样),因为它可以正常使用Firefox。但任何意见都非常感谢。

UPD:我尝试用getWebDriver()。findElement(By.xpath(&#34; xpath_string&#34;)替换无法在BasePage.class找到的WebElement,并且它有效。所以&# 39;关于BasePage.class的东西。如果我理解正确,由于某种原因它无法与BaseTest.class通信。

0 个答案:

没有答案