使用Selenium+Cucumber+TestNG切换浏览器时遇NoSuchSessionException问题
我使用Selenium+Cucumber+TestNG框架进行自动化测试,被测应用无登出功能,需在Feature用例执行过程中关闭当前浏览器并重新打开以切换不同用户登录,但执行时报错org.openqa.selenium.NoSuchSessionException: invalid session id。
相关代码
Feature文件
@Regression @Recall Scenario: Validate workflow with Recall from Closed tab Given User launch the "MISToolkit" application on browser When "approver" logs in to application Then "MISToolKit" page should appear Then User navigates to "ResearchTicketDashboard" page Then User navigates to WorkQueue on Research Ticket Dashboard Page And I "close" the browser for logging in as another analyst When User launch the "MISToolkit" application on browser When "analyst" logs in to application
步骤定义代码
@Then("I {string} the browser for logging in as another analyst") public void closeTheSessionForLoggingInAsOtherAnalyst(String mode) { researchTicketDashboardPage.clearBrowserStorage(mode); }
clearBrowserStorage方法实现
driver.close(); Base.initializeBrowserSetup();
报错信息
When User launch the "MISToolkit" application on browser # stepDefinitions.LoginPageStepDefinitions.userLaunchTheApplicationOnBrowser(java.lang.String) org.openqa.selenium.NoSuchSessionException: invalid session id
问题原因
driver.close()执行后,原WebDriver会话已失效,但Base.initializeBrowserSetup()创建的新driver实例没有覆盖全局的driver变量,导致后续步骤仍在使用已失效的旧会话对象,触发了会话无效的异常。
解决方案
更新全局WebDriver实例
修改Base.initializeBrowserSetup()方法,确保返回新创建的WebDriver对象,并在clearBrowserStorage中覆盖全局driver:// Base类的初始化方法 public static WebDriver initializeBrowserSetup() { // 根据你的浏览器配置创建新实例,示例为ChromeDriver return new ChromeDriver(); } // clearBrowserStorage方法修改 public void clearBrowserStorage(String mode) { driver.close(); // 将全局driver替换为新实例 driver = Base.initializeBrowserSetup(); }优先使用quit()彻底销毁会话
如果需要完全结束旧会话再重建,建议用driver.quit()替代driver.close(),确保旧会话资源被彻底释放,避免残留问题:public void clearBrowserStorage(String mode) { driver.quit(); driver = Base.initializeBrowserSetup(); }检查页面类的driver引用
确保所有页面类中的driver引用都指向全局最新实例,比如页面类通过构造方法接收全局driver,或直接访问Base类的静态driver变量,避免持有旧实例的引用。TestNG配置校验
若TestNG用例采用单例运行模式,需确保切换用户时不会复用旧driver实例。可在@AfterMethod或切换步骤中彻底清理旧driver资源,保证每次初始化都是全新会话。
内容的提问来源于stack exchange,提问作者Pratik

