Selenium无法打开浏览器,抛出null异常求助
从你的代码和堆栈信息来看,这几个问题是导致异常的核心原因,咱们逐个拆解修复:
1. 配置文件读取时未正确初始化输入流(最关键问题)
你在ReadConfigFile的构造函数里调用了getResourceAsStream读取配置文件,但没把返回的流赋值给input变量,导致input一直是null。后续prop.load(input)会抛出IO异常,最终prop也是null,调用getBrowser()就返回空字符串,DriverFactory里的switch找不到匹配的浏览器,driver保持null,到finally块调用driver.manage()直接触发空指针异常。
修复后的ReadConfigFile.java:
package Utils; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ReadConfigFile { protected InputStream input = null; protected Properties prop = null; public ReadConfigFile() { try { // 关键:把读取到的流赋值给input变量 input = ReadConfigFile.class.getClassLoader().getResourceAsStream(Constant.CONFIG_PROPERTIES_DIRECTORY); if (input == null) { throw new IOException("找不到配置文件:" + Constant.CONFIG_PROPERTIES_DIRECTORY); } prop = new Properties(); prop.load(input); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("加载配置文件失败", e); // 主动抛出异常,避免后续使用null的配置 } finally { if (input != null) { try { input.close(); // 关闭流,避免资源泄漏 } catch (IOException e) { e.printStackTrace(); } } } } public String getBrowser() { // 增加默认值,避免返回空字符串 return prop.getProperty("browser", "chrome").trim(); } }
2. WebDriver系统属性键写错了
在DriverFactory里,设置驱动路径的系统属性键是错的:
- Firefox的正确键是
webdriver.gecko.driver,你写的是webdriver.geckodriver - Chrome的正确键是
webdriver.chrome.driver,你写的是webdriver.chromedriver
修复后的驱动属性设置代码:
// Firefox驱动配置 System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY); // Chrome驱动配置 System.setProperty("webdriver.chrome.driver", Constant.CHROME_DRIVER_DIRECTORY);
3. Mac下驱动路径拼接错误
Constant里拼接路径时,user.dir后面没加路径分隔符,拼出来的路径会变成/Users/你的用户名CucumberFramework/...这种错误格式,肯定找不到驱动文件。咱们用File.separator来拼接,兼容所有操作系统。另外Mac下的驱动文件需要可执行权限,要是运行还是报错,记得在终端执行:
chmod +x /你的驱动文件完整路径/geckodriver chmod +x /你的驱动文件完整路径/chromedriver
修复后的Constant.java:
package Utils; import java.io.File; public class Constant { public final static String CONFIG_PROPERTIES_DIRECTORY = "properties/config.properties"; // 用File.separator拼接路径,跨平台兼容 public final static String GECKO_DRIVER_DIRECTORY = System.getProperty("user.dir") + File.separator + "CucumberFramework" + File.separator + "src" + File.separator + "test" + File.separator + "java" + File.separator + "Resources" + File.separator + "geckodriver"; public final static String CHROME_DRIVER_DIRECTORY = System.getProperty("user.dir") + File.separator + "CucumberFramework" + File.separator + "src" + File.separator + "test" + File.separator + "java" + File.separator + "Resources" + File.separator + "chromedriver"; }
4. Finally块缺少空指针防护
在DriverFactory的getDriver()方法中,finally块不管try块是否成功都会执行,如果driver初始化失败(比如配置文件读取错误),driver还是null,此时调用driver.manage()会直接抛出空指针异常,需要先判断driver是否为null。
修复后的DriverFactory完整代码:
package Utils; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.PageFactory; import pageObjects.AddIssuePage; import pageObjects.Login_Page; import java.util.concurrent.TimeUnit; public class DriverFactory { public static WebDriver driver; public static Login_Page login_page; public static AddIssuePage addIssuePage; public WebDriver getDriver() { try { ReadConfigFile file = new ReadConfigFile(); String browserName = file.getBrowser(); // 转小写,避免配置文件中大小写不匹配 switch (browserName.toLowerCase()) { case "firefox": if (null == driver) { System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY); DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability("marionette", true); driver = new FirefoxDriver(capabilities); } break; case "chrome": if (null == driver) { System.setProperty("webdriver.chrome.driver", Constant.CHROME_DRIVER_DIRECTORY); driver = new ChromeDriver(); } break; default: throw new RuntimeException("不支持的浏览器类型:" + browserName); } } catch (Exception e) { System.out.println("Unable to load browser: " + e.getMessage()); throw new RuntimeException("初始化浏览器失败", e); // 抛出异常,避免后续使用null的driver } finally { if (driver != null) { driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS); login_page = PageFactory.initElements(driver, Login_Page.class); addIssuePage = PageFactory.initElements(driver, AddIssuePage.class); } } return driver; } }
内容的提问来源于stack exchange,提问作者moh17

