基于Selenium+Java+JUnit的Page Objects项目NullPointerException求助
解决Selenium Page Object模式中的NullPointerException问题
我来帮你排查这个空指针异常的问题,看了你的代码后,核心问题出在多个类的WebDriver变量互相独立,没有正确传递初始化后的实例上,具体原因和修复方案如下:
为什么会抛出NullPointerException?
在你的测试类LogarBkoMaisTest中,你定义了一个静态的WebDriver driver,但在setUp方法里调用nav.iniciarNavegador()后,并没有把方法返回的driver实例赋值给测试类的driver变量。同时,SelecionarNavegador和LogarBkoMaisPage里都各自定义了静态的WebDriver driver,这三个静态变量是完全独立的实例——也就是说,SelecionarNavegador初始化的是自己的driver,而测试类的driver始终是null。
当你执行LogarBkoMaisPage login = new LogarBkoMaisPage(driver)时,传入的是测试类的null driver,后续调用login.logar()时,自然会因为driver为null而抛出空指针异常。
具体修复步骤
1. 移除所有不必要的静态WebDriver变量
静态变量会导致不同类的driver实例互相隔离,我们把所有类里的static WebDriver driver改成非静态(或局部变量):
修改LogarBkoMaisPage类:
public class LogarBkoMaisPage { WebDriver driver; // 去掉static修饰符 By campoNome = By.id("matricula_I"); By campoSenha = By.id("senha_I"); By btnLogin = By.id("bt_entrar"); public LogarBkoMaisPage(WebDriver driver) { this.driver = driver; } public void logar(String usuario, String senha) { driver.findElement(campoNome).sendKeys(usuario); driver.findElement(campoSenha).sendKeys(senha); driver.findElement(btnLogin).click(); } }
修改SelecionarNavegador类:
public class SelecionarNavegador { // 移除类级别的静态driver,改用方法内的局部变量 public static WebDriver iniciarNavegador(String nomeNavegador, String url) { WebDriver driver = null; if(nomeNavegador.equalsIgnoreCase("firefox")) { System.setProperty("webdriver.gecko.driver", "E:\\workspace_BCC_QA_BKOMAIS\\" + "FireFoxGeckodriver64\\geckodriver.exe"); driver = new FirefoxDriver(); } else if(nomeNavegador.equalsIgnoreCase("chrome")){ System.setProperty("webdriver.chrome.driver", "E:\\workspace_BCC_QA_BKOMAIS" + "\\chromedriver_win32\\chromedriver.exe"); driver = new ChromeDriver(); }else if(nomeNavegador.equalsIgnoreCase("IE")) { System.setProperty("webdriver.ie.driver", "E:\\workspace_BCC_QA_BKOMAIS" + "\\IE Plugin\\IEDriverServer.exe"); driver = new InternetExplorerDriver(); } // 增加非空判断,避免driver为null时调用方法 if(driver != null){ driver.manage().window().maximize(); driver.get(url); } return driver; } }
2. 在测试类中正确接收并传递driver实例
修改LogarBkoMaisTest,将iniciarNavegador()返回的driver赋值给测试类的driver变量,同时在tearDown中关闭浏览器释放资源:
public class LogarBkoMaisTest { WebDriver driver; // 去掉static修饰符 @Before public void setUp() throws Exception { // 接收浏览器初始化后的driver实例 driver = SelecionarNavegador.iniciarNavegador("ie","http://10.5.9.45/BkoMais_Selenium/"); } @Test public void logarAplicacao() { try { LogarBkoMaisPage login = new LogarBkoMaisPage(driver); login.logar("844502","Bcc201707"); }catch(Exception e) { System.out.println("Mensagem de erro: " +e); e.printStackTrace(); // 打印完整堆栈,方便后续排查问题 } } @After public void tearDown() throws Exception { // 测试结束后关闭浏览器,避免残留进程 if(driver != null){ driver.quit(); } } }
额外优化建议
- 在
SelecionarNavegador的iniciarNavegador方法中,增加对nomeNavegador的非空判断,避免传入null导致新的空指针; - 尽量不要使用静态变量存储WebDriver,保持实例的独立性,避免测试用例之间互相干扰;
- 捕获异常时优先打印完整堆栈信息,比单纯打印错误消息更有助于定位问题。
内容的提问来源于stack exchange,提问作者Leandro Pereira
相关产品推荐
相关产品推荐

