基于Java、Selenium、Cucumber和JUnit Runner复用浏览器实例执行多场景测试
复用单个Chrome Driver实例执行所有测试场景的解决方案
你的问题核心是当前每个测试场景都会重复启动/关闭浏览器,导致登录流程反复执行浪费时间。下面是具体修改方案,实现单Driver实例全流程复用:
1. 修改BaseClass,增加Driver复用逻辑
调整Driver初始化逻辑,仅当Driver未创建时才实例化,避免重复启动浏览器:
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.JavascriptExecutor; import io.github.bonigarcia.wdm.WebDriverManager; import java.time.Duration; public class BaseClass { public static WebDriver driver; public static JavascriptExecutor jse; public static void setUp() throws Exception { // 仅在Driver未初始化时创建新实例 if (driver == null || driver.toString().contains("null")) { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); jse = (JavascriptExecutor) driver; } } // 全局关闭方法,仅在所有测试结束后调用 public static void tearDownGlobal() { if (driver != null) { driver.quit(); driver = null; // 重置状态,避免后续测试异常 } } }
2. 调整Hooks类,实现全局启停+场景级截图
修改钩子逻辑,让浏览器只在所有测试启动前初始化一次,每个场景结束后仅执行截图操作,所有测试完成后再统一关闭浏览器:
import cucumber.api.java.After; import cucumber.api.java.AfterAll; import cucumber.api.java.BeforeAll; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; public class Hooks { private static ConfigFileReader reader; private static Properties pro; // 全局前置:所有Feature执行前仅运行一次,可在此完成登录 @BeforeAll public static void launchBrowserOnce() { reader = new ConfigFileReader(); pro = reader.ConfigFile(); try { BaseClass.setUp(); // 可选:在这里添加全局登录逻辑,避免每个场景重复登录 // LoginPage.login(pro.getProperty("username"), pro.getProperty("password")); } catch (Exception e) { e.printStackTrace(); } } // 场景后置:每个测试场景结束后截图,不关闭浏览器 @After public void afterScenario(cucumber.api.Scenario scenario) { File destPath; SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy_hh.mm.ss"); String strDate = sdf.format(new Date()); File screenshot = ((TakesScreenshot) BaseClass.driver).getScreenshotAs(OutputType.FILE); if (scenario.isFailed()) { destPath = new File("./test-output/Screenshots/Failed/" + scenario.getName() + strDate + ".png"); } else { destPath = new File("./test-output/Screenshots/Passed/" + scenario.getName() + strDate + ".png"); } try { FileUtils.copyFile(screenshot, destPath); } catch (IOException e) { e.printStackTrace(); } } // 全局后置:所有测试执行完成后,关闭浏览器 @AfterAll public static void tearDownBrowserOnce() { BaseClass.tearDownGlobal(); } }
3. 注意事项
- Cucumber版本兼容:
@BeforeAll和@AfterAll需要Cucumber 7.x及以上版本支持,若使用旧版本,可通过静态标志位替代:private static boolean isBrowserLaunched = false; @Before(order = 0) public void launchBrowser() { if (!isBrowserLaunched) { // 初始化逻辑同@BeforeAll isBrowserLaunched = true; } } - 串行测试要求:单Driver实例仅支持串行测试,需确保测试执行配置为串行(如JUnit设置
parallel=none),并行测试会导致场景间状态干扰。 - 场景状态清理:若不同场景需要干净的初始状态,可在每个场景前执行页面重置(如回到首页、清除缓存),避免场景间状态污染。
内容的提问来源于stack exchange,提问作者Maxwell Maragia
相关产品推荐
相关产品推荐

