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
相关产品推荐
相关产品推荐

