基于Cucumber搭建BDD框架时遇URL加载异常及空指针问题
Cucumber BDD框架空指针异常与浏览器重复打开问题修复
问题描述
- 触发空指针异常,报错:
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebDriver.get(String)" because "this.driver" is null - Chrome浏览器打开两次,调试发现driver对象为null,URL无法正常打开
问题根源
- driver引用传递错误:步骤类初始化
Baseclass和Loginpage时,传入的是未初始化的null值,后续Baseclass中创建的driver实例无法同步到其他类的引用。 - 重复实例化driver:类之间重复创建
Baseclass实例,导致多次初始化ChromeDriver,引发浏览器重复打开。 - PageFactory初始化时机错误:driver未初始化时就调用
PageFactory.initElements,导致页面元素绑定失败,后续操作触发空指针。
修复方案及修改后代码
步骤定义文件(steps.java)
public class steps { private WebDriver driver; private Baseclass base; private Loginpage login; public static Logger logfile = LogManager.getLogger(steps.class.getName()); @Given("open chrome browser") public void openBrowser() { base = new Baseclass(); driver = base.initiatingDriver(); // 获取初始化后的driver实例 login = new Loginpage(driver); // 用已初始化的driver创建Loginpage } @And("Login to application url") public void loginAppicaltionUrl() { login.openUrlLogin("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"); } @And("^enter the valid \"(.*)\"$") public void enterValidUsername(String username) { login.enteringUsername(username); } @And("^enter valid \"(.*)\"$") public void enterValidPassword(String password) { login.enteringPassword(password); } }
Baseclass类
public class Baseclass { private WebDriver driver; public static Logger logfile = LogManager.getLogger(Baseclass.class.getName()); public static String parentWindow; // 无参构造,避免传入null driver public Baseclass() { } public WebDriver initiatingDriver() { driver = new ChromeDriver(); driver.manage().window().maximize(); PageFactory.initElements(driver, this); // driver初始化完成后再绑定PageFactory return driver; } public void openUrl() throws Throwable{ driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"); threadsleep(5000); logfile.info("Url opened successfully"); } public void sendKeysUsingCss(WebElement element,String username) { driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(40)); element.sendKeys(username); } public void threadsleep(long ms) throws InterruptedException { Thread.sleep(ms); } }
Loginpage类
public class Loginpage { private WebDriver driver; private Baseclass base; public Loginpage(WebDriver driver) { this.driver = driver; this.base = new Baseclass(); PageFactory.initElements(driver, this); // 确保driver已初始化再绑定元素 } @FindBy(how=How.CSS, using="input[name^='username']") private WebElement name; @FindBy(how=How.CSS,using="input[name^='password']") private WebElement passwrd; public void openUrlLogin(String url) { try { driver.get(url); driver.manage().window().maximize(); base.threadsleep(5000); base.logfile.info("Url opened successfully"); } catch (Throwable e) { e.printStackTrace(); System.out.println(e); Assert.fail("Url not opened"); } } public void enteringUsername(String username) { name.sendKeys(username); } public void enteringPassword(String password) { passwrd.sendKeys(password); } }
关键修复说明
- 统一driver生命周期:由步骤类集中管理driver的创建,确保所有类共享同一个driver实例,避免null引用。
- 延迟PageFactory初始化:在driver实例化完成后再调用
PageFactory.initElements,保证页面元素正确绑定。 - 避免重复创建实例:移除类内部自动创建
Baseclass的逻辑,防止多次初始化ChromeDriver导致浏览器重复打开。
内容的提问来源于stack exchange,提问作者guru
相关产品推荐
相关产品推荐

