如何在页面对象工厂模式中将静态WebDriver改为非静态?
页面对象工厂模式:将静态WebDriver改为非静态并避免空指针异常
需要将页面对象工厂模式中的静态WebDriver改为非静态实现,同时解决页面对象间共享WebDriver时可能出现的空指针异常问题。以下是现有代码及修改方案:
一、修改基类 Page
原代码中driver为静态变量,改为非静态后,每个页面对象实例可持有独立或共享的driver实例,避免静态变量带来的线程安全问题和空指针风险:
原Page类代码
public class Page { @Getter @Setter public static WebDriver driver; public Page(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } }
修改后的Page类代码
import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.PageFactory; import lombok.Getter; public class Page { // 移除static修饰符,改为非静态成员变量 @Getter private WebDriver driver; public Page(WebDriver driver) { // 提前校验入参,避免后续空指针 if (driver == null) { throw new IllegalArgumentException("WebDriver实例不能为null"); } this.driver = driver; PageFactory.initElements(driver, this); } }
说明:去掉@Setter,确保driver仅在构造时初始化,后续不允许随意修改;添加非空校验从源头规避空指针。
二、修改步骤定义类 LandingPageStepDefs
原代码直接引用未初始化的静态driver,极易触发空指针。需确保WebDriver实例化完成后,再传入页面对象:
原LandingPageStepDefs代码
import static utils.Page.driver; public class LandingPageStepDefs { private LandingPage landingPage = new LandingPage(driver); @And("Customer does something") public void customerDoesSomething() { landingPage.doSomething(); } }
修改后的LandingPageStepDefs代码
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import io.cucumber.java.Before; import io.cucumber.java.After; public class LandingPageStepDefs { private WebDriver driver; private LandingPage landingPage; // 测试执行前初始化WebDriver与页面对象 @Before public void setup() { // 示例为ChromeDriver,可替换为其他浏览器驱动 driver = new ChromeDriver(); landingPage = new LandingPage(driver); } @And("Customer does something") public void customerDoesSomething() { landingPage.doSomething(); } // 测试结束后销毁WebDriver,避免资源泄漏 @After public void teardown() { if (driver != null) { driver.quit(); } } }
说明:通过@Before确保driver初始化完成后再创建页面对象;@After统一销毁driver,规范资源管理。
三、修改页面对象类 LandingPage
原代码存在构造方法位置错误,修正后确保正确继承基类并传入driver:
原LandingPage代码
public class LandingPage extends Page { @FindBy(xpath = "this is xpath") private WebElement pageWebElement; } public LandingPage(WebDriver driver) { super(driver); } public void doSomething() { pageWebElement.click(); }
修改后的LandingPage代码
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; public class LandingPage extends Page { @FindBy(xpath = "this is xpath") private WebElement pageWebElement; // 构造方法移至类内部,正确调用父类构造 public LandingPage(WebDriver driver) { super(driver); } public void doSomething() { pageWebElement.click(); } }
说明:修正类结构错误,父类已完成driver非空校验,子类无需重复处理。
核心注意点
- 禁止提前初始化页面对象:不要在类成员变量声明时直接创建页面对象,必须等待WebDriver实例化完成后再创建。
- 非空校验前置:在基类构造中添加driver非空判断,提前抛出异常便于排查问题。
- 生命周期统一管理:通过
@Before和@After控制WebDriver的创建与销毁,确保测试用例的独立性或共享性符合需求。
内容的提问来源于stack exchange,提问作者Word Place
相关产品推荐
相关产品推荐

