Java 和 Selenium:页面对象中的静态方法
当我尝试在页面对象中使用静态方法时,我遇到了 NullPointerExceptions 问题.如果我使用非静态方法,它工作正常.
I'm having trouble with NullPointerExceptions when I try using static methods in a page object. If I do it with non-static methods, it works fine.
非静态版本:
public class ComplaintPage {
private ExtendedWebDriver driver;
@FindBy(css = "[data-selector=date-received-complaint]")
public WebElement dateComplaintReceoved;
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
public void setComplaintDate() {
dateComplaintReceoved.sendKeys(LocalDate.now().toString());
}
}
Calling code:
ComplaintPage complaintPage = new ComplaintPage;
complaintPage.setComplaintDate();
这很好用.日期字段已设置.
This works fine. The date field is set.
静态版
public class ComplaintPage {
private static ExtendedWebDriver driver;
@FindBy(css = "[data-selector=date-received-complaint]")
public static WebElement dateComplaintReceoved;
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
public void static setComplaintDate() {
* dateComplaintReceoved.sendKeys(LocalDate.now().toString());
}
}
Calling code:
ComplaintPage.setComplaintDate();
这不起作用,并在标有*"的行(访问 WebElement 的行)上导致 java.lang.NullPointerException.
This does not work, and results in a java.lang.NullPointerException on the line marked with "*" (the line accessing the WebElement).
我有点喜欢在测试中使用像这样的静态方法,因为我真的看不出它有什么问题,而且它使代码更易于阅读.我以前在 C#/VS 中做过,但由于某种原因,我在这里遗漏了一些重要的东西.
I kind of like using static methods like this in test, since I don't really see a problem with it, and it makes the code even more easy to read. And I've done it before, in C#/VS, but for some reason I'm missing something important here.
推荐答案
NullPointerException
因为 PageFactory
的工作方式而被抛出.你看,当你创建一个 ComplaintPage
类的实例时,你正在调用它的构造函数:
NullPointerException
is thrown because of how PageFactory
works. You see, when you create an instance of ComplaintPage
class, you are invoking its constructor:
public ComplaintPage() {
driver = Browser.extendedDriver();
PageFactory.initElements(driver, this);
}
构造函数调用PageFactory
类的initElements
方法.此方法使用 Java 反射 API 初始化所有 WebElement
和 List
null
值更改为接口的实现.它还提供了一种 WebElement 的惰性实例化,这意味着 - WebElement
仅在需要时才被发现(寻找?) - 当您调用它们的操作时.
The constructor calls initElements
method of PageFactory
class. This method initializes all of WebElement
and List<WebElement
> fields with Java Reflection API. It basically changes the default null
values to implementations of the interface. It also provides sort of Lazy instantiation of the WebElement which means - WebElement
s are found (looked for?) only when needed - when you invoke operations on them.
当您创建静态方法和静态 WebElements 时 - 您没有调用类的构造函数,这导致不调用 initElements
方法.
When you created static methods and static WebElements - you did not call the constructor of the class, which lead to NOT invoking the initElements
method.
使用 @FindBy
注释的所有元素均未初始化.这就是为什么将 PageFactory 与静态方法一起使用并不是一个好主意.
All of the elements annotated with @FindBy
were not initialized. That's why it's not a good idea to use PageFactory with static methods.
您可以在静态方法中找到带有经典 driver.findElement
的元素,而不是使用 PageFactory.
Instead of using PageFactory you can just find the element with classic driver.findElement
inside the static method.
public void static setComplaintDate(WebDriver driver) {
driver.findElement(By.cssSelector("[data-selector=date-received-complaint]")).sendKeys(LocalDate.now().toString());
}
相关文章