如何在同一Chrome窗口中运行多个Selenium+Java测试?
Selenium复用Chrome窗口完成SSO手动登录后的测试执行
问题描述
我们使用Selenium+Java进行Chrome浏览器的应用测试,当前系统切换为需要手动干预的单点登录(SSO)机制。希望实现:启动一个ChromeDriver窗口,手动完成SSO登录后,让所有后续测试用例都在这个已登录的窗口中运行,请问该方案是否可行?如何实现?
当前使用的setup方法代码如下:
@Before public void setup() throws Exception { logger.debug("running test {}#{}()", testClassName, testMethodName); Class<?> webDriverClass = Class.forName(webDriverClassName); if (ChromeDriver.class.equals(webDriverClass)) { ChromeOptions options = getChromeOptions(); driver = new ChromeDriver(options); } driver.manage().timeouts().implicitlyWait(webDriverDefaultTimeout); wait = new WebDriverWait(driver, webDriverDefaultTimeout) { @SuppressWarnings("unused") public <V> V until(Function<? super WebDriver, V> isTrue) { long start = System.currentTimeMillis(); try { return super.until(isTrue); } finally { logger.debug("waited {} ms", System.currentTimeMillis() - start); } } @SuppressWarnings("unused") public void until(ExpectedCondition<Boolean> isTrue) { long start = System.currentTimeMillis(); try { super.until(isTrue); } finally { logger.debug("waited {} ms", System.currentTimeMillis() - start); } } }; seleniumUtils.setWait(wait); seleniumUtils.setDriver(driver); driver.manage().window().maximize(); }
方案可行性与实现步骤
完全可行,核心思路是复用Chrome的用户数据目录保留登录状态,或者直接复用已打开的浏览器会话。下面是两种具体实现方式:
方式一:复用Chrome用户数据目录(推荐,稳定性高)
Chrome的用户数据目录会存储Cookie、登录状态、缓存等信息,只要在指定目录下完成过SSO登录,后续启动的ChromeDriver会自动加载这些信息,保持登录状态。
1. 修改ChromeOptions配置
在getChromeOptions()方法中添加用户数据目录的指定:
private ChromeOptions getChromeOptions() { ChromeOptions options = new ChromeOptions(); // 自定义本地文件夹路径,用来存储Chrome的用户数据 String userDataDir = "C:\\selenium_chrome_test_profile"; // 可替换为你自己的路径 options.addArguments("user-data-dir=" + userDataDir); // 可选:指定具体的子profile,默认是Default,也可以自定义名称 // options.addArguments("profile-directory=SSOTestProfile"); return options; }
2. 调整测试初始化逻辑
将driver和wait改为静态变量,通过@BeforeClass只初始化一次,确保所有测试用例复用同一个浏览器窗口:
// 改为静态变量,全局复用同一个浏览器实例 private static WebDriver driver; private static WebDriverWait wait; @BeforeClass public static void initGlobalDriver() throws Exception { logger.debug("初始化全局ChromeDriver实例"); Class<?> webDriverClass = Class.forName(webDriverClassName); if (ChromeDriver.class.equals(webDriverClass)) { ChromeOptions options = getChromeOptions(); driver = new ChromeDriver(options); // 暂停执行,等待手动完成SSO登录,完成后按回车继续 System.out.println("请手动完成SSO登录,操作完成后按回车键继续测试..."); new java.util.Scanner(System.in).nextLine(); } driver.manage().timeouts().implicitlyWait(webDriverDefaultTimeout); wait = new WebDriverWait(driver, webDriverDefaultTimeout) { @Override public <V> V until(Function<? super WebDriver, V> isTrue) { long start = System.currentTimeMillis(); try { return super.until(isTrue); } finally { logger.debug("等待时长: {} ms", System.currentTimeMillis() - start); } } @Override public void until(ExpectedCondition<Boolean> isTrue) { long start = System.currentTimeMillis(); try { super.until(isTrue); } finally { logger.debug("等待时长: {} ms", System.currentTimeMillis() - start); } } }; seleniumUtils.setWait(wait); seleniumUtils.setDriver(driver); driver.manage().window().maximize(); } @Before public void perTestSetup() throws Exception { logger.debug("运行测试 {}#{}()", testClassName, testMethodName); // 这里只做单测前的准备工作,比如导航到测试页面,无需重新初始化driver } @AfterClass public static void destroyGlobalDriver() { if (driver != null) { driver.quit(); } }
方式二:复用已打开的Chrome会话(临时测试用)
如果不想创建新的用户数据目录,可以先手动打开Chrome并完成登录,再让Selenium连接这个已有的窗口:
- 手动启动Chrome时,添加启动参数:
chrome.exe --remote-debugging-port=9222 - 在Selenium中配置ChromeOptions连接该端口:
ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("debuggerAddress", "localhost:9222"); driver = new ChromeDriver(options);
这种方式需要提前手动打开Chrome并完成登录,适合临时调试,但稳定性不如方式一。
内容的提问来源于stack exchange,提问作者Kristie
相关产品推荐
相关产品推荐

