通过super()传递WebDriver至父类仍触发NullPointerException问题
解决WebDriver通过super传递后父类仍出现NullPointerException的问题
问题根源
Java类的实例化顺序是:先初始化所有类级别的实例变量,再执行构造器中的代码。
你在父类PageElements中直接定义了WebElement searchBox = driver.findElement(...),这段代码会在构造器给this.driver赋值之前执行,此时driver还是默认的null,调用findElement自然抛出空指针异常。
解决方案
方案1:将WebElement初始化移至构造器
修改父类代码,把元素初始化逻辑放到构造器中,确保driver赋值完成后再查找元素:
package TestPackageForStructure; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class PageElements { WebDriver driver; WebElement searchBox; public PageElements(WebDriver driver) { this.driver = driver; // 构造器赋值后再初始化元素 this.searchBox = driver.findElement(By.xpath("//*[@id=\"APjFqb\"]")); } }
方案2:使用懒加载(调用时再初始化)
如果不想在构造阶段初始化元素(比如页面还未加载完成),可以在需要使用元素时再执行查找逻辑:
package TestPackageForStructure; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; public class PageElements { WebDriver driver; public PageElements(WebDriver driver) { this.driver = driver; } // 懒加载获取元素 private WebElement getSearchBox() { return driver.findElement(By.xpath("//*[@id=\"APjFqb\"]")); } // 对外提供操作元素的方法 public void enterSearchText(String text) { getSearchBox().sendKeys(text); } }
对应的子类修改为:
package TestPackageForStructure; import io.qameta.allure.Step; import org.openqa.selenium.WebDriver; public class PageSteps extends PageElements { public PageSteps(WebDriver driver) { super(driver); } @Step public void inputData(String text) { enterSearchText(text); } }
方案3:使用Selenium PageFactory(推荐)
Selenium的PageFactory支持延迟初始化元素,既解决初始化顺序问题,也能避免页面未加载时查找元素失败:
package TestPackageForStructure; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class PageElements { WebDriver driver; // 用@FindBy注解声明元素定位 @FindBy(xpath = "//*[@id=\"APjFqb\"]") WebElement searchBox; public PageElements(WebDriver driver) { this.driver = driver; // 初始化PageFactory,延迟加载元素 PageFactory.initElements(driver, this); } }
额外优化
测试类中建议先打开页面,再初始化页面对象,避免因页面未加载导致元素查找失败:
import TestPackageForStructure.PageSteps; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.annotations.Test; public class TestStructure { @Test public void insertSomeData() throws InterruptedException { WebDriver driver = new ChromeDriver(); driver.get("https://www.google.com/"); // 先加载页面,再初始化页面对象 PageSteps pageSteps = new PageSteps(driver); Thread.sleep(5000); pageSteps.inputData("Hello World"); // 测试完成后关闭浏览器 driver.quit(); } }
内容的提问来源于stack exchange,提问作者Davit Ebralidze
相关产品推荐
相关产品推荐

