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

Cucumber调用Page Object方法时WebDriver空指针异常求助

解决Cucumber+POM中的WebDriver空指针异常(NPE)

问题描述

运行Cucumber数据驱动测试时,调用Page Object方法触发空指针异常,错误信息如下:

Cannot invoke "org.openqa.selenium.WebDriver.findElement(org.openqa.selenium.By)" because "this.driver" is null

根本原因

  1. Pom对象初始化时机错误:在PomTest类中,Pom pom=new Pom(driver);是在类加载阶段执行的,此时driver还未被实例化(driver=new ChromeDriver()要等到user_launches_the_browser步骤才执行),导致传递给Pom构造器的是null。
  2. Pom类中driver被定义为static:静态变量会被所有测试场景共享,不仅违反POM的实例化设计原则,还会引发线程安全问题。

修复方案

  1. 移除Pom类中driver的static修饰符,改为实例变量。
  2. 延迟Pom对象的初始化,确保在driver实例化完成后再创建Pom实例。
  3. 优化测试代码的稳定性(可选但推荐)。

修正后的代码

Pom类(pages.Pom)

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class Pom {
    
    // 移除static修饰符,改为实例变量
    WebDriver driver;
    
    By username = By.xpath("//*[@id='user-name']");
    By password = By.xpath("//*[@id='password']");
    By loginbutton = By.xpath("//*[@id='login-button']");
    By logout = By.xpath("//*[contains(text(),'Logout')]");
    By open_menu = By.xpath("//*[contains(text(),'Open Menu')]");
    
    public Pom(WebDriver driver) {
        this.driver = driver;
        // 页面校验逻辑:用IllegalArgumentException替代IO相关的IIOException更合理
        if (!driver.getTitle().equals("Swag Labs")) {
            throw new IllegalArgumentException("当前页面不是登录页,URL:" + driver.getCurrentUrl());
        }
    }
    
    public void enter_username(String username1) {
        driver.findElement(username).sendKeys(username1);
    }
    
    public void enter_password(String password1) {
        driver.findElement(password).sendKeys(password1);
    }
    
    public void click_login() {
        driver.findElement(loginbutton).click();
    }

    public void check_logout() {
        driver.findElement(logout).isDisplayed();
    }
    
    public void click_open_menu() {
        driver.findElement(open_menu).click();
    }
}

Step定义类(StepDefinations.PomTest)

package StepDefinations;

import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.cucumber.java.en.*;
import io.github.bonigarcia.wdm.WebDriverManager;
import pages.Pom;

public class PomTest {
    
    public WebDriver driver;
    Pom pom; // 仅声明,不提前初始化
    
    @Given("User launches the browser")
    public void user_launches_the_browser() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(6));
        driver.manage().window().maximize();
    }
    
    @Given("user navigate to the Login landing Page")
    public void user_navigate_to_the_login_landing_page() throws InterruptedException {
        driver.navigate().to("https://www.saucedemo.com/");
        Thread.sleep(3000);
        // 此时driver已实例化,初始化Pom对象
        pom = new Pom(driver);
    }
    
    @When("^User enters the credentials as (.+) and (.+) $")
    public void user_enters_the_credentials_as_and(String username, String password) throws Throwable {
        pom.enter_username(username);
        Thread.sleep(3000);
        pom.enter_password(password);
        Thread.sleep(3000);
    }
    
    @And("User clicks on the login button after entering credentials")
    public void user_clicks_on_the_login_button_after_entering_credentials() {
        pom.click_login();
    }
    
    @Then("User lands on the user account home page and checks the logout button")
    public void user_lands_on_the_user_account_home_page_and_checks_the_logout_button() {
        pom.click_open_menu();
        pom.check_logout();
    }
    
    @Then("the user closes the browser")
    public void the_user_closes_the_browser() {
        driver.quit(); // 用quit关闭所有浏览器窗口,比close更彻底
    }
}

Feature文件(修正拼写错误)

Feature: Login functionality Test 
Scenario Outline: Verify the login of the user on the particular website 
    Given User launches the browser 
    And user navigate to the Login landing Page
    When User enters the credentials as <username> and <password> 
    And User clicks on the login button after entering credentials 
    Then User lands on the user account home page and checks the logout button
    And the user closes the browser

    Examples:
    |username|password|
    |standard_user|secret_sauce|
    |locked_out_user|secret_sauce|
    |problem_user|secret_sauce|
    |performance_glitch_user|secret_sauce|

额外建议

  • 替换Thread.sleep()为显式等待(WebDriverWait),提高测试稳定性,例如等待元素可交互后再操作。
  • 注意locked_out_user场景会登录失败,当前测试步骤会报错,建议拆分成功/失败场景分别编写预期逻辑。

内容的提问来源于stack exchange,提问作者user3857859

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:31:21