Cucumber与Selenium使用POM模式时Driver为空引发空指针异常问题
POM+PageFactory抛出NullPointerException的原因及解决
问题现象
使用Page Object Model(POM)结合Page Factory和Base类时,持续抛出以下异常:
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.SearchContext.findElement(org.openqa.selenium.By)" because "this.searchContext" is null
或提示driver为空,无法点击目标链接。但直接在步骤定义类中查找元素时可正常运行。
相关代码
Base类
public class Base { public static WebDriver driver; public static WebDriverWait wait; public static void startBrowser(String browser, String url){ if (browser.equalsIgnoreCase("chrome")){ driver = new ChromeDriver(); } else if (browser.equalsIgnoreCase("firefox")) { driver = new FirefoxDriver(); } else if (browser.equalsIgnoreCase("edge")) { driver = new EdgeDriver(); } wait = new WebDriverWait(driver, Duration.ofSeconds(30)); driver.manage().window().maximize(); driver.get(url); } }
HomePage类
public class HomePage extends Base { @FindBy(xpath = "//li[@id='menu-item-324']//a") public WebElement loginLink; public HomePage(){ PageFactory.initElements(driver,this); } public void clickLoginLink(){ loginLink.click(); } }
步骤定义类
public class LoginSteps extends Base { HomePage home = new HomePage(); @Given("user opens a a browser") public void user_opens_a_a_browser() throws InterruptedException { startBrowser("chrome", "domain.com"); } @When("user enters the url") public void user_enters_the_url() { System.out.println("entered url");; } @And("clicks on login link") public void clicksOnLoginLink() { home.clickLoginLink(); } @Then("user navigated to domain.com") public void user_navigated_to_domain_com() { System.out.println("navigated to"); } }
Feature文件
Feature: feature to test to validate login Scenario: Check login with valid credentials Given user opens a a browser When user enters the url And clicks on login link Then user navigated to domain.com
原因分析
核心问题是HomePage实例化时机错误:
在LoginSteps中,HomePage home = new HomePage();是在类加载阶段就执行的,此时startBrowser()方法还未调用,Base类中的static driver仍然是null。
当HomePage构造函数执行PageFactory.initElements(driver,this)时,传入的driver为null,导致Page Factory无法初始化元素,后续调用loginLink.click()自然会抛出空指针异常。
解决办法
方法一:延迟HomePage实例化
修改LoginSteps,在driver初始化完成后再创建HomePage对象:
public class LoginSteps extends Base { HomePage home; // 仅声明,不提前初始化 @Given("user opens a a browser") public void user_opens_a_a_browser() throws InterruptedException { startBrowser("chrome", "domain.com"); home = new HomePage(); // 此时driver已被初始化,可正常传递给PageFactory } // 其他方法保持不变 }
方法二:优化架构(长期方案)
避免使用static driver,改用Cucumber的依赖注入(如PicoContainer)来管理driver和页面对象的生命周期,这样既能解决空指针问题,也能避免静态变量在并行测试时引发的线程安全问题。
内容的提问来源于stack exchange,提问作者Ami
相关产品推荐
相关产品推荐

