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

Selenium/Cucumber/TestNG自动化:父类driver实例空指针异常

解决Cucumber框架中Hook传递Driver实例后getDriver()返回null的问题

问题原因

你的Hooks类和GoogleSearchSteps类都继承了BaseTest,但Cucumber会分别创建这两个类的独立实例。Hooks中初始化的driver属于Hooks实例的成员变量,而GoogleSearchSteps调用getDriver()时,访问的是自身实例中未初始化的driver,因此返回null。

解决方案:使用单例模式共享Driver实例

通过将BaseTest改造为单例模式,确保测试流程中始终只有一个BaseTest实例,从而让Hooks和步骤定义类共享同一个driver对象。

修改后的BaseTest类

package utilities;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import dataProviders.ConfigFileReader;
import io.github.bonigarcia.wdm.WebDriverManager;

public class BaseTest {
    
    // 单例实例
    private static BaseTest instance;
    public WebDriver driver;
    ConfigFileReader config = new ConfigFileReader();
    
    // 私有构造方法,禁止外部直接实例化
    private BaseTest(){}
    
    // 获取全局唯一的单例实例
    public static BaseTest getInstance(){
        if(instance == null){
            instance = new BaseTest();
        }
        return instance;
    }
    
    public void openBrowser() {
        // 仅当driver未初始化时创建实例
        if(driver == null){
            switch(config.getBrowser()){
                case CHROME:
                    WebDriverManager.chromedriver().setup();
                    driver = new ChromeDriver();
                    break;
                case FIREFOX:
                    WebDriverManager.firefoxdriver().setup();
                    driver = new FirefoxDriver();
                    break;
                case EDGE:
                    WebDriverManager.edgedriver().setup();
                    driver = new EdgeDriver();
                    break;
            }
        }
    }
    
    public WebDriver getDriver() {
        return driver;
    }
    
    public void navigateToSite(String str) {
        driver.navigate().to(str);
    }
    
    public void waitForPageToLoad(){
        driver.manage().timeouts().implicitlyWait(config.getImplicitWait(), TimeUnit.SECONDS);
        driver.manage().timeouts().pageLoadTimeout(config.getPageLoadTimeout(), TimeUnit.SECONDS);
    }
        
    public void closeBrowser(){
        if(null != driver) {
            System.out.println("Executing close");
            driver.close();
            driver.quit();
            driver = null; // 重置driver,方便下一次测试重新初始化
            instance = null; // 重置单例实例
        }
    }
}

修改后的Hooks类

package StepDefinitions;

import io.cucumber.java.After;
import io.cucumber.java.Before;
import utilities.BaseTest;

public class Hooks {
    
    private BaseTest baseTest;
    
    public Hooks(){
        // 获取单例实例
        baseTest = BaseTest.getInstance();
    }
    
    @Before
    public void setUp(){
        baseTest.openBrowser();
    }
    
    @After
    public void tearDown() {
        baseTest.closeBrowser();
    }
}

修改后的GoogleSearchSteps类

package StepDefinitions;

import dataProviders.ConfigFileReader;
import io.cucumber.java.en.*;
import pages.googlesearch;
import utilities.BaseTest;

public class GoogleSearchSteps {

    googlesearch gs;
    ConfigFileReader configFileReader;
    private BaseTest baseTest;

    public GoogleSearchSteps(){
        // 获取同一个单例实例
        baseTest = BaseTest.getInstance();
    }

    @Given("browser window is open")
    public void browser_is_open() {
        gs = new googlesearch(baseTest.getDriver());
        baseTest.waitForPageToLoad();        
        configFileReader = new ConfigFileReader();
    }

    @And("user is on google search page")
    public void user_is_on_google_search_page() {
        System.out.println("Inside Step - user is on google search page");
        baseTest.navigateToSite(configFileReader.getApplicationUrl());
    }

    @When("user enters a text in search box")
    public void user_enters_a_text_in_search_box() throws InterruptedException {
        System.out.println("Inside Step - user enters a text in search box");
        gs.enterSearchTerm(configFileReader.getSearchTerm());
    }

    @And("hits enter")
    public void hits_enter() throws InterruptedException {
        System.out.println("Inside Step - hits enter");
        gs.hitEnterForSearchTerm();
    }

    @Then("user is navigated to search results")
    public void user_is_navigated_to_search_results() {
        System.out.println("Inside Step - user is navigated to search results");
        gs.getPageSource(configFileReader.getPageSource()); 
    }
}

说明

改造后,Hooks和GoogleSearchSteps通过BaseTest.getInstance()获取同一个实例,所有操作都指向同一个driver对象,彻底解决了getDriver()返回null的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:27:55