Selenium-Spring测试中WebDriver与页面对象自动装配及多用例失败修复
解决Spring + Selenium多测试用例运行时WebDriver会话失效问题
问题根源
你的WebDriver Bean默认是**单例(Singleton)**作用域,所有测试方法共享同一个实例。第一个测试执行完@AfterEach里的driver.quit()会关闭浏览器会话,第二个测试拿到的仍是这个已失效的WebDriver实例,自然抛出NoSuchSessionException。
解决方案:调整WebDriver Bean的作用域
把WebDriver的Bean作用域改为方法级别(method)或原型(prototype),让每个测试方法都能获取全新的WebDriver实例。
1. 使用method作用域(推荐)
Spring Test提供的method作用域会为每个测试方法生成独立的Bean实例,完全适配测试场景:
@Configuration public class WebDriverConfig { @Bean @Scope("method") // 每个测试方法生成新的WebDriver实例 public WebDriver webDriver() { ChromeOptions options = new ChromeOptions(); // 可根据需求添加配置,比如无头模式 options.addArguments("--headless=new", "--disable-gpu"); return new ChromeDriver(options); } }
2. 使用prototype作用域
如果你的Spring版本不支持method作用域,可改用原型作用域,同时配合@DirtiesContext确保每个测试方法后销毁当前Bean:
@Configuration public class WebDriverConfig { @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public WebDriver webDriver() { // 同上文的WebDriver初始化逻辑 ChromeOptions options = new ChromeOptions(); options.addArguments("--headless=new"); return new ChromeDriver(options); } }
在测试类上添加@DirtiesContext:
@SpringBootTest @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) public class AppTests extends BaseTest { // 测试方法... }
配套代码调整
确保Base类的@AfterEach只关闭当前测试方法的WebDriver实例:
public class BaseTest { @Autowired protected WebDriver driver; @AfterEach public void tearDown() { if (driver != null) { driver.quit(); } } }
页面对象类通过构造注入WebDriver(Spring会自动注入对应作用域的实例):
@Component public class LoginPage { private final WebDriver driver; @Autowired public LoginPage(WebDriver driver) { this.driver = driver; } // 页面操作方法示例 public void enterUsername(String username) { driver.findElement(By.id("username")).sendKeys(username); } }
注意事项
method作用域是Spring Test特有的,仅在测试环境生效,无需担心生产环境的Bean作用域问题。- 避免使用
@AfterAll关闭WebDriver,否则会导致所有测试共用一个驱动实例,容易产生状态污染(比如前一个测试的页面残留影响后一个测试)。
内容的提问来源于stack exchange,提问作者spring-qa
相关产品推荐
相关产品推荐

