You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cucumber多场景执行异常:仅首个场景运行其余被忽略排查

问题描述

在一个Cucumber Feature文件中创建了多个登录场景,单独执行每个场景均正常无报错,但执行整个Feature文件时,仅首个场景执行成功,其余场景步骤被忽略,抛出如下错误:

org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?

问题原因
  • Spring默认Bean作用域为单例(Singleton),WebDriver实例一旦创建就会被所有场景复用
  • 在Hooks类的@After方法中调用了webDriver.quit(),销毁了第一个场景的浏览器会话
  • 后续场景执行时,注入的仍是已被quit的WebDriver实例,会话已失效,导致报错
解决方案

1. 修改WebDriver配置类,设置Bean为原型作用域

将WebDriver Bean的作用域改为prototype,确保每个场景都会创建全新的WebDriver实例:

@Configuration
public class WebDriverLibrary {
    @Value("${remote.url}")
    private URL remoteUrl;

    @Value("${browser}")
    private String browser;

    @Bean
    @Scope("prototype") // 新增:设置原型作用域
    public WebDriver getChromeDriver(){
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--remote-allow-origins=*");
        return new ChromeDriver(chromeOptions);
    }
}

2. 调整Hooks类,管理每个场景的WebDriver生命周期

通过ApplicationContext获取原型Bean,确保每个场景使用独立的WebDriver,并在场景结束后销毁:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.openqa.selenium.WebDriver;
import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import org.springframework.beans.factory.annotation.Value;

public class Hooks {
    @Autowired
    private ApplicationContext context;

    private WebDriver webDriver;

    @Value("${app.url}")
    private String appUrl;

    @Before
    public void InitializeTest(Scenario scenario){
        // 每次场景开始时获取新的WebDriver实例
        webDriver = context.getBean(WebDriver.class);
        webDriver.navigate().to(appUrl);
        webDriver.manage().window().maximize();
    }

    @After
    public void TearDownTest(Scenario scenario){
        if(scenario.isFailed()){
            System.out.println(scenario.getName());
        }
        if(webDriver != null){
            webDriver.quit(); // 显式销毁当前场景的WebDriver会话
        }
    }
}

3. 调整Step Definition中的Page元素初始化

由于WebDriver变为原型,需要确保Page元素绑定当前场景的WebDriver实例,可在Step类中添加初始化逻辑:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.junit.Assert;

public class LoginSteps {
    private WebDriver webDriver;

    @Autowired
    private ApplicationContext context;

    @Autowired
    private LandingPage landingPage;

    @Autowired
    private LoginPage loginPage;

    @Autowired
    private SignUpPage signUpPage;

    @Autowired
    private QuestionnairePage questionnairePage;

    @Before // Cucumber的Before注解,在每个场景步骤前执行
    public void setUp() {
        webDriver = context.getBean(WebDriver.class);
        // 重新初始化所有Page元素,绑定当前WebDriver
        PageFactory.initElements(webDriver, landingPage);
        PageFactory.initElements(webDriver, loginPage);
        PageFactory.initElements(webDriver, signUpPage);
        PageFactory.initElements(webDriver, questionnairePage);
    }

    @Given("User is on Landing Page")
    public void userIsOnLandingPage() {
        Assert.assertTrue(landingPage.btnGetStarted.isDisplayed());
    }

    // 其余步骤代码保持不变...
}
额外疑问解答

问:未使用webDriver.quit()时浏览器也会关闭,是否需要添加@After注解?
答:

  • 必须保留@After注解并显式调用webDriver.quit(),原因如下:
    1. 浏览器自动关闭通常是测试进程结束后JVM回收WebDriver实例触发的,属于被动回收,无法保证会话资源(如驱动进程、临时文件)完全释放,易引发内存泄漏
    2. webDriver.quit()会主动终止WebDriver会话,彻底销毁浏览器实例和相关资源,确保测试环境干净
    3. 统一的teardown逻辑能避免后续场景受前序场景的残留状态影响,保证测试稳定性

内容的提问来源于stack exchange,提问作者Santhiya s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:37:57