Selenium WebDriver出现Session ID null异常的原因及解决求助
解决org.openqa.selenium.NoSuchSessionException异常问题
问题原因
第一个测试用例执行完成后,@AfterMethod中调用Driver.closeDriver()关闭了WebDriver会话,但测试类中类级别的页面对象实例(LoginAndSignUpPage loginAndSignUpPage=new LoginAndSignUpPage();)会一直持有已关闭会话的WebElement引用。后续测试用例启动新的WebDriver会话时,旧页面对象的元素仍然绑定在已失效的旧会话上,导致抛出Session ID is null异常。
解决方案
1. 每次测试前重新初始化页面对象
将页面对象的初始化从类级别移到@BeforeMethod中,确保每个测试用例都使用新WebDriver会话对应的页面对象:
public class LoginTests extends TestBase{ private LoginAndSignUpPage loginAndSignUpPage; @BeforeMethod public void setUpPage() { // 每个测试方法执行前,创建新的页面对象实例 loginAndSignUpPage = new LoginAndSignUpPage(); } @Test (priority = 1) public void loginWithValidCredentials(){ // 原有测试逻辑不变 loginAndSignUpPage.navigateToModule("Log in"); loginAndSignUpPage.login_userName.sendKeys(ConfigurationReader.get("username")); loginAndSignUpPage.login_password.sendKeys(ConfigurationReader.get("password")); loginAndSignUpPage.login_button.click(); String expectedUser= "Welcome " + ConfigurationReader.get("username"); Assert.assertEquals(expectedUser, loginAndSignUpPage.nameOfUser.getText()); } // 其他测试方法逻辑不变 }
2. 完善Driver类的closeDriver方法
确保关闭Driver会话后,清理ThreadLocal中的引用,避免残留已失效的Driver实例:
public class Driver { private Driver(){} private static InheritableThreadLocal<WebDriver> driverPool = new InheritableThreadLocal<>(); public static WebDriver get(){ // 原有创建Driver的逻辑不变 if (driverPool.get() == null){ String browser = System.getProperty("browser") != null ? System.getProperty("browser") : ConfigurationReader.get("browser"); switch (browser){ case "chrome": WebDriverManager.chromedriver().setup(); ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); driverPool.set(new ChromeDriver(options)); driverPool.get().manage().window().maximize(); driverPool.get().manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); break; } } return driverPool.get(); } public static void closeDriver() { if (driverPool.get() != null) { driverPool.get().quit(); // 移除ThreadLocal中的Driver引用,确保下次get()会创建新实例 driverPool.remove(); } } }
3. 修复测试方法中的语法与逻辑错误
第二个测试方法存在多余注释符号、未声明变量的问题,需修正:
@Test (priority = 2) public void loginWithInvalidPassword(){ loginAndSignUpPage.navigateToModule("Log in"); loginAndSignUpPage.login_userName.sendKeys(ConfigurationReader.get("username")); loginAndSignUpPage.login_password.sendKeys("wrongpassword"); // 移除多余的) loginAndSignUpPage.login_button.click(); Alert alert = Driver.get().switchTo().alert(); // 补充分明alert变量 String actual = alert.getText(); String expected = "Wrong password."; Assert.assertEquals(expected, actual); alert.accept(); // 处理alert,避免后续操作阻塞 }
4. 替换硬编码等待为显式等待
避免使用强制等待,改用WebDriverWait提升测试稳定性:
// 在测试方法中使用TestBase中初始化的wait对象 Alert alert = wait.until(ExpectedConditions.alertIsPresent());
内容的提问来源于stack exchange,提问作者Umran Erdogan
相关产品推荐
相关产品推荐

