Selenium中@FindBy注解能否用于接口?初始化失败问题
Selenium中@FindBy注解能否用于接口?
嘿,我来帮你捋清楚这个问题~首先直接给结论:@FindBy注解不能直接用于接口来初始化WebElement,你的代码能编译但元素没法正常初始化,核心问题就在这里。
为什么你的代码编译正常但元素无法初始化?
Java里接口的成员变量默认是public static final的,哪怕你没显式写出来。而Selenium的PageFactory.initElements()是通过反射去初始化类里非静态、非final的字段——它根本没法处理接口里这些被默认设为不可修改常量的WebElement变量,自然没法给它们赋值,所以你的UsernameField和PswdField最终都是null。
正确的解决方案
如果想把页面元素定义抽离出来复用,推荐用抽象类代替接口,这也是页面对象模型(POM)里常用的做法:
public abstract class HomePageObjects { @FindBy(xpath = "//*[@class='_2zrpKA']") protected WebElement UsernameField ; @FindBy(xpath = "//*[@class='_2zrpKA _3v41xv']") protected WebElement PswdField ; } public class HomePageTests extends HomePageObjects { WebDriver Driver; @BeforeClass public void initpage() { Driver = LaunchBrowser.Driver; PageFactory.initElements(Driver, this); System.out.println(UsernameField + " " + Driver); } }
这么做的好处很明显:
- 抽象类的成员变量默认不是static final的,PageFactory可以正常通过反射初始化它们
- 既保留了元素定义的复用性,又符合Java继承的设计逻辑,用起来简洁高效
如果你实在想用接口,也可以通过“接口+实现类注解”的方式,但这样会多写不少重复代码,不太推荐:
public interface HomePageObjects { WebElement getUsernameField(); WebElement getPswdField(); } public class HomePageTests implements HomePageObjects { WebDriver Driver; @FindBy(xpath = "//*[@class='_2zrpKA']") private WebElement UsernameField ; @FindBy(xpath = "//*[@class='_2zrpKA _3v41xv']") private WebElement PswdField ; @BeforeClass public void initpage() { Driver = LaunchBrowser.Driver; PageFactory.initElements(Driver, this); } @Override public WebElement getUsernameField() { return UsernameField; } @Override public WebElement getPswdField() { return PswdField; } }
内容的提问来源于stack exchange,提问作者Bhanu Bhaskar
相关产品推荐
相关产品推荐

