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

Selenium PageObject项目无法定位页面元素空指针异常排查

问题背景

基于PageObject设计模式从零搭建Selenium自动化测试项目时,代码运行失败,Selenium WebDriver无法定位网页元素,抛出如下空指针异常:

java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.SearchContext.findElement(org.openqa.selenium.By)" because "this.searchContext" is null

涉及代码

DriverBase.java

该类用于完成驱动初始化配置

package com.EbankingA11y.base;

import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import com.EbankingA11y.util.WebListener;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class DriverBase {
       
        protected static final Logger LOG = (Logger) LogManager.getLogger(WebListener.class);

        public static WebDriver driver;
        public static Properties prop;
        public static FileInputStream fis;
        
        public DriverBase()  {
            
            prop = new Properties();
            
            try {
                fis = new FileInputStream("C:\\Users\\config.properties");
            } catch (FileNotFoundException exception) {
                exception.printStackTrace();
                LOG.debug(" Error \n " +exception.getStackTrace());

            }
            try {
                prop.load(fis);
            } catch (IOException exception) {
                exception.printStackTrace();
                LOG.debug(" Error \n " +exception.getStackTrace());
            }
        }
        
        public static void initialization () throws InterruptedException {
            System.setProperty("webdriver.chrome.driver", prop.getProperty("WEB_DRIVER_PATH") );
            //WebDriverManager.chromedriver().setup();
            
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.setAcceptInsecureCerts(true);

            driver = new ChromeDriver(chromeOptions);
            driver.manage().window().maximize();
            driver.get(prop.getProperty("URL"));
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        }
    }

LoginPage.java

该类用于定义登录页的所有页面元素及对应操作方法

import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.EbankingA11y.base.DriverBase;

public class LoginPage extends DriverBase {

    public LoginPage() {
        PageFactory.initElements(DriverBase.driver, this);
    }
    @FindBy(name="username")
    WebElement usernameTextBox;
    
    @FindBy(name="password")
    WebElement passwordTextBox;
    
    @FindBy(xpath="//input[@value=\\\"Use 'Enter' to confirm\\\"]")
    WebElement submitButton;
    
    @FindBy(xpath="//button[@name='button']")
    WebElement languageButton;  
            
    @FindBy(name="smsCode")
    WebElement tokenTextBox;


    public void performLogin () {
        //WebDriverWait wait = new WebDriverWait(driver,30);

        final String username = prop.getProperty("USERNAME");
        final String password = prop.getProperty("PASSWORD");
        System.out.println(username);

        //wait.until(ExpectedConditions.visibilityOf(this.usernameTextBox));
        usernameTextBox.clear();
        passwordTextBox.clear();
        usernameTextBox.sendKeys(username);
        passwordTextBox.sendKeys(password);
        
        submitButton.click();
        
        //wait.until(ExpectedConditions.visibilityOf(this.tokenTextBox));

    }
}

LoginPageTests.java

该类用于编写测试用例,调用LoginPage.java类中的封装方法

package com.EbankingA11y.testcases;

import java.io.IOException;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.EbankingA11y.base.*;
import com.EbankingA11y.pages.LoginPage;


public class LoginPageTest extends DriverBase {
    

    public LoginPageTest() throws IOException {
        super();
    }
    
    LoginPage loginPage = new LoginPage();
    
    @BeforeTest
    public void setup() throws InterruptedException {
        initialization();
    }

    @Test
    public void login()  {
        loginPage.performLogin();
    }
}

故障原因
  • 页面对象初始化时机错误:LoginPage实例是在测试类的成员变量位置直接创建的,这部分代码会在@BeforeTest标注的setup()方法执行前运行,此时initialization()还未调用,DriverBase.driver是null值,PageFactory.initElements()传入了空的driver对象,后续操作元素时就会抛出searchContext为空的空指针异常。
  • 元素定位表达式写法错误:submitButton的xpath里多了不必要的转义反斜杠,即使driver初始化正常,也无法定位到对应按钮。

修复方法
  • 调整LoginPage实例化位置:将页面对象的初始化逻辑移到setup()方法中,确保driver初始化完成后再创建页面对象,修改后LoginPageTest的核心代码如下:
public class LoginPageTest extends DriverBase {
    
    LoginPage loginPage;

    public LoginPageTest() throws IOException {
        super();
    }
    
    @BeforeTest
    public void setup() throws InterruptedException {
        initialization();
        // driver初始化完成后再实例化页面对象
        loginPage = new LoginPage();
    }

    @Test
    public void login()  {
        loginPage.performLogin();
    }
}
  • 修正submitButton的xpath定位表达式,去掉多余的转义符:
@FindBy(xpath="//input[@value=\"Use 'Enter' to confirm\"]")
WebElement submitButton;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:54:28