
在Selenium多浏览器并行/顺序测试中,若复用同一WebDriver实例变量(如driver)启动多个浏览器,@After钩子仅能关闭最后一个赋值的驱动,导致其他浏览器残留——根本原因在于对象引用被覆盖,而非quit()失效。
在selenium多浏览器测试中,若复用同一`webdriver`实例变量(如`driver`)启动多个浏览器,`@after`钩子仅能关闭最后一个赋值的驱动,导致其他浏览器残留——根本原因在于对象引用被覆盖,而非`quit()`失效。
当您在Cucumber步骤定义中连续调用 website_works_on_firefox()、website_works_on_chrome() 和 website_works_on_edge() 时,每次都会对同一个 driver 字段重新赋值:
driver = new FirefoxDriver(); // ← 此引用被后续覆盖 driver = new ChromeDriver(options); // ← 覆盖上一个,FirefoxDriver对象失去引用 driver = new EdgeDriver(); // ← 再次覆盖,ChromeDriver对象也失去引用
此时,只有 EdgeDriver 实例保留在 driver 变量中;@After tearDown() 中执行 driver.quit() 仅关闭 Edge 浏览器,而 Firefox 和 Chrome 进程因无有效引用且未显式关闭,持续驻留后台。
✅ 正确做法:为每个浏览器维护独立的 WebDriver 引用,并在 tearDown() 中统一管理关闭逻辑。推荐使用 ThreadLocal
public class MS848Steps {
private List<WebDriver> drivers = new ArrayList<>();
@When("Website works on Firefox")
public void website_works_on_firefox() {
WebDriver firefoxDriver = new FirefoxDriver();
drivers.add(firefoxDriver);
firefoxDriver.get("https://demowebshop.tricentis.com/");
System.out.println("Website works on Firefox!");
}
@And("Website works on Chrome")
public void website_works_on_chrome() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver chromeDriver = new ChromeDriver(options);
drivers.add(chromeDriver);
chromeDriver.get("https://demowebshop.tricentis.com/");
System.out.println("Website works on Chrome!");
}
@And("Website works on Edge")
public void website_works_on_edge() {
WebDriver edgeDriver = new EdgeDriver();
drivers.add(edgeDriver);
edgeDriver.get("https://demowebshop.tricentis.com/");
System.out.println("Website works on Edge!");
}
@Then("Website works on every browser")
public void website_works_on_every_browser() {
System.out.println("Website works on every browser!");
}
@After
public void tearDown() {
// 逆序关闭(可选),确保所有驱动都被清理
for (int i = drivers.size() - 1; i >= 0; i--) {
WebDriver driver = drivers.get(i);
if (driver != null) {
try {
driver.quit(); // 推荐:关闭会话 + 浏览器进程
} catch (Exception e) {
System.err.println("Failed to quit driver: " + e.getMessage());
}
}
}
drivers.clear();
}
}⚠️ 注意事项:
- 勿混用 close() 与 quit():close() 仅关闭当前窗口,quit() 才终止整个会话并释放资源;
- 避免静态或全局 WebDriver 字段:易引发线程安全问题与引用泄漏;
- 启用日志/超时增强健壮性:可在 ChromeOptions 中添加 options.setHeadless(true) 或 options.addArguments("--no-sandbox") 适配CI环境;
- 若需并发执行多浏览器,应配合 @ScenarioScoped(Cucumber PicoContainer)或 ThreadLocal 隔离驱动实例。
通过解耦浏览器驱动生命周期,每个 WebDriver 实例均可被精准追踪与释放,彻底解决“浏览器残留”这一高频陷阱。


















