如何在GitLab CI中配置Selenium文件下载自动化测试
问题根因
- 本地运行时,测试代码和docker服务都在同一主机,你在代码中配置的
download.default_directory指向的本地target路径,和docker-compose挂载到chrome容器的/home/seluser/Downloads是同一个物理路径,所以匹配正常。 - GitLab CI环境下,你使用了Docker-in-Docker(Dind)模式运行selenium服务:测试代码跑在
chrome-test任务的独立容器中,chrome浏览器跑在docker-compose启动的独立selenium-node-chrome容器里。你当前代码中设置的下载路径是测试代码容器的本地target路径,而RemoteWebDriver模式下,下载路径配置是作用于浏览器所在的远端节点,两端路径不匹配导致文件下载后无法被测试代码读取,触发断言失败。 - 额外常见原因:selenium-node-chrome容器内运行浏览器的用户是uid为1200的
seluser,GitLab CI中默认生成的target目录没有写入权限,导致chrome无法写入下载文件。
修复方案
- 修正下载路径配置
RemoteWebDriver模式下,download.default_directory需要配置为浏览器所在容器的内部路径,修改你的Selenium配置代码:
// 替换原来的folder.getAbsolutePath(),直接写chrome容器内的下载路径 prefs.put("download.default_directory", "/home/seluser/Downloads");
- 修复挂载目录权限
在gitlab-ci.yml的chrome-test任务的script段,启动docker-compose前修改target目录权限,允许seluser用户写入:
script: - apk add --no-cache docker-compose - apk add openjdk11 - chmod 777 ./target # 新增这行,或者用chown 1200:1200 ./target更安全 - docker-compose down - docker-compose up --build --force-recreate --no-deps -d - echo "Hello, chrome-test" - chmod +x ./gradlew - ./gradlew :test --tests "LogInTest_chrome"
- 优化等待逻辑
当前2秒固定等待容易因为网络波动导致下载未完成就触发断言,替换为轮询等待更稳定:
@Test public void downloadFileTest() throws InterruptedException { driver.get("http://the-internet.herokuapp.com/download"); driver.findElement(By.linkText("some-file.txt")).click(); // 替换固定Thread.sleep,最多等待10秒 int maxWait = 10; while (maxWait > 0 && folder.listFiles().length == 0) { Thread.sleep(1000); maxWait--; } File listOffFiles[] = folder.listFiles(); Assert.assertTrue(listOffFiles.length > 0); for(File file : listOffFiles) { Assert.assertTrue(file.length() > 0); } }
GitLab CI排查方法
如果修改后依然失败,可以通过以下步骤定位问题:
- 在测试代码中增加目录日志
在断言前打印target目录下的所有文件信息,确认测试代码侧是否能读取到文件:
File listOffFiles[] = folder.listFiles(); System.out.println("target目录文件数量:" + listOffFiles.length); for (File file : listOffFiles) { System.out.printf("文件名:%s,文件大小:%d字节%n", file.getName(), file.length()); }
- 在CI脚本中增加目录检查命令
在测试运行结束后分别检查CI环境的target目录、chrome容器内的下载目录内容:
script: # ... 原有脚本不变 - ./gradlew :test --tests "LogInTest_chrome" - ls -la ./target # 查看CI环境target目录文件 - docker exec chrome ls -la /home/seluser/Downloads # 查看chrome容器内下载目录文件
- 把target目录加入流水线制品
修改gitlab-ci.yml的artifacts配置,流水线结束后可以直接下载target目录查看内容:
artifacts: when: always reports: junit: build/test-results/test/**/TEST-*.xml paths: - build/reports/* - target/* # 新增这行 expire_in: 1 day
内容的提问来源于stack exchange,提问作者AutoBeginner
相关产品推荐
相关产品推荐

