Java Spring Cucumber注入PageObject时的WebDriver会话管理问题
WebDriver会话管理问题解决方案(基于配置注入不同PageObject实现)
问题场景
在Cucumber的Scenario Outline中执行测试时,第一个示例运行正常,但第二个示例调用注入的IProductDetailsPage实例时抛出异常:
org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
相关代码
Page实现配置类(PageImplConfig)
@Configuration public class PageImplConfig { @Value("${application.url}") private String url; @Bean public IProductDetailsPage pdp() { if(url.contains("www.somesite.com")) { return new ProductDetailsPageHG(); } else { return new ProductDetailsPageDefault(); } } }
WebDriver配置类
@Bean @Scope("browserscope") @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public WebDriver chromeDriver(){ ChromeOptions options = new ChromeOptions(); options.addArguments("--remote-allow-origins=*"); WebDriverManager.chromedriver().setup(); return new ChromeDriver(options); }
Step类中的注入代码
public class PdpSteps extends SpringBaseTestNGTest { @Autowired protected IProductDetailsPage pdp; }
问题根源
- Page Bean作用域不匹配:当前
IProductDetailsPage的Bean是默认单例作用域,整个Spring容器仅创建一个实例。第一个示例执行完毕后WebDriver会话被关闭,但Page实例仍持有失效的WebDriver引用,第二个示例复用该实例时就会抛出会话为空的异常。 - 自定义作用域未同步Page实例:WebDriver使用了
browserscope自定义作用域,但Page实例还是单例,导致每个测试示例无法获取绑定当前会话的新Page实例。
解决步骤
1. 调整Page Bean的作用域
将IProductDetailsPage的Bean作用域改为与WebDriver一致的browserscope,确保每个测试会话都能拿到新的Page实例,避免复用失效的WebDriver引用:
@Configuration public class PageImplConfig { @Value("${application.url}") private String url; @Bean @Scope("browserscope") // 新增作用域注解,与WebDriver保持一致 public IProductDetailsPage pdp() { if(url.contains("www.somesite.com")) { return new ProductDetailsPageHG(); } else { return new ProductDetailsPageDefault(); } } }
2. 让Page类通过依赖注入获取WebDriver
检查ProductDetailsPageHG和ProductDetailsPageDefault的实现,确保它们不直接创建WebDriver实例,而是通过Spring注入对应作用域的WebDriver:
// 以ProductDetailsPageHG为例 public class ProductDetailsPageHG implements IProductDetailsPage { private final WebDriver driver; // 构造函数注入WebDriver,Spring自动匹配对应作用域的实例 public ProductDetailsPageHG(WebDriver driver) { this.driver = driver; } // 页面方法实现... }
3. 验证自定义作用域与Cucumber的同步
确保browserscope自定义作用域能正确绑定到Cucumber的每个Scenario Outline示例(即每个测试会话)。如果是自定义实现的作用域,要保证它会在每个测试实例启动时创建新Bean,测试结束后销毁并关闭WebDriver会话。
内容的提问来源于stack exchange,提问作者Alex Smoke
相关产品推荐
相关产品推荐

