IntelliJ中Selenium登录E2E测试WebDriver空指针异常求助
执行Selenium登录功能E2E测试时,持续抛出空指针异常:
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebDriver.findElement(org.openqa.selenium.By)" because "SeleniumE2E.E2ETest.driver" is null
测试代码如下:
package SeleniumE2E; import org.junit.jupiter.api.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxOptions; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; public class E2ETest { public static WebDriver driver; @BeforeMethod public void setUp() { try { System.setProperty("webdriver.gecko.driver", "C:\\Users\\picom\\Downloads\\geckodriver-v0.34.0-win64\\geckodriver.exe"); FirefoxOptions options = new FirefoxOptions(); options.addArguments("--headless"); driver = new FirefoxDriver(options); driver.get("http://www.google.com"); //driver.quit(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("WebDriver initialization failed"); } } @Test public void testLogin() { WebElement emailInput = driver.findElement(By.id("email")); emailInput.sendKeys("mariya@gmail.com"); WebElement passwordInput = driver.findElement(By.id("password")); passwordInput.sendKeys("MAriya12!"); WebElement loginButton = driver.findElement(By.xpath("//button[text()='Login']")); loginButton.click(); String currentUrl = driver.getCurrentUrl(); assertEquals("http://localhost:8080/Main.html", currentUrl); } @AfterMethod public void tearDown() { if (driver != null) { driver.quit(); } } }
附带的LoginRequestDto代码:
package com.example.demo.dto; public class LoginRequestDto { private String email; private String password; public LoginRequestDto() { } // Getters and Setters public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
以及login.html代码:
<!DOCTYPE html> <html> <head> <title>User Login</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f4f4f4; } h2 { color: #333; text-align: center; } form { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); max-width: 400px; margin: 20px auto; } label { display: block; margin: 10px 0 5px; } input[type=text], input[type=password] { width: 100%; padding: 10px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } button { background-color: #008cba; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 20px; } button:hover { background-color: #005f73; } </style> </head> <body> <h2>User Login</h2> <form id="loginForm"> <label for="email">Email:</label> <input type="text" id="email" name="email" required> <label for="password">Password:</label> <input type="password" id="password" name="password" required> <button type="button" onclick="login()">Login</button> </form> <p>Don't have an account? <a href="register">Register here</a>.</p> <script> function login() { var email = document.getElementById("email").value; var password = document.getElementById("password").value; var loginData = { email: email, password: password }; fetch('/api/user/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(loginData) }) .then(response => { if (response.redirected) { window.location.href = response.url; } else { console.error('Login failed'); alert('Invalid email or password'); } }) .catch(error => { console.error('Error:', error); alert('Error occurred while logging in'); }); } </script> </body> </html>
已尝试切换Firefox驱动、修改driver访问修饰符为public static,均未解决问题,寻求其他修复方案。
1. 统一测试框架注解
代码混合使用了JUnit 5(org.junit.jupiter.api.Test)和TestNG(@BeforeMethod、@AfterMethod)的注解,导致@BeforeMethod(TestNG)不会被JUnit 5执行,driver从未初始化。
修复方式二选一:
- 改用TestNG:替换
import org.junit.jupiter.api.Test;为import org.testng.annotations.Test;,确保测试运行器配置为TestNG; - 改用JUnit 5:替换
@BeforeMethod、@AfterMethod为JUnit 5的@BeforeEach、@AfterEach,对应导入import org.junit.jupiter.api.BeforeEach;、import org.junit.jupiter.api.AfterEach;。
示例(JUnit 5版本):
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; // 其他导入保持不变 public class E2ETest { public WebDriver driver; // 移除static修饰符 @BeforeEach public void setUp() { // 原有初始化逻辑不变 } @Test public void testLogin() { // 原有测试逻辑不变 } @AfterEach public void tearDown() { // 原有销毁逻辑不变 } }
2. 修正测试页面地址
setUp中当前打开的是http://www.google.com,但测试代码要查找登录页面的email、password元素,谷歌页面不存在这些元素。需要将driver.get("http://www.google.com")改为你的登录页面实际地址,例如http://localhost:8080/login.html。
3. 移除不必要的static修饰符
将public static WebDriver driver;改为public WebDriver driver;即可,static会导致多测试方法共享同一driver,容易引发并发问题,而JUnit 5/TestNG的前置方法会为每个测试方法独立初始化driver。
4. 检查GeckoDriver兼容性
确保GeckoDriver版本与Firefox浏览器版本匹配:
- Firefox 115+ 对应GeckoDriver 0.33+;
- 若Firefox是新版本,建议升级GeckoDriver至最新稳定版。
5. 增强初始化异常排查
在setUp的catch块中补充详细错误输出,确认是否是路径错误或浏览器启动失败导致driver未初始化:
catch (Exception e) { System.err.println("WebDriver初始化失败原因:" + e.getMessage()); e.printStackTrace(); throw new RuntimeException("WebDriver initialization failed", e); }
内容的提问来源于stack exchange,提问作者Kate

