You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在页面对象工厂模式中将静态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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:03:17