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

Azure Pipeline中Selenium测试无法获取下载文件问题

解决Azure Pipeline中Selenium下载PDF后找不到文件的问题

我来帮你排查这个问题——你遇到的FileNotFoundException是因为在Azure Pipeline的Ubuntu虚拟机环境里,PDF文件要么没被正确下载到指定路径,要么路径本身存在权限或不存在的问题。下面是具体的排查和解决步骤:

1. 先确保目标下载目录存在且有权限

Windows本地的项目目录结构是现成的,但Azure Pipeline的Ubuntu Agent是临时构建环境,src/test/resources目录可能还没创建,或者Agent用户没有写入权限。

解决方案:

  • 在测试代码里先检查并创建目录:
String downloadDirPath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "test" + File.separator + "resources";
File downloadDir = new File(downloadDirPath);
// 递归创建多级目录,避免单个目录不存在的情况
if (!downloadDir.exists()) {
    downloadDir.mkdirs();
}
// 再把路径设置到Chrome偏好里
prefs.put("download.default_directory", downloadDirPath);
  • 或者在Pipeline的Gradle任务前,先通过Bash命令创建目录(双重保险):
    修改你的yml文件:
jobs:
  - job: Test Running
    timeoutInMinutes: 180
    pool:
      vmImage: ubuntu-20.04
    continueOnError: true
    steps:
      - bash: mkdir -p src/test/resources
        displayName: Create download directory
      - task: Gradle@2
        displayName: Run Tests against UK Region
        inputs:
          gradleWrapperFile: gradlew
          tasks: test

2. 配置无头Chrome的下载参数(关键)

Azure Pipeline里运行Selenium通常是用无头模式的Chrome,而无头模式默认的下载行为和正常模式不一样,必须额外配置才能让文件下载到指定目录。

更新你的Selenium ChromeOptions配置:

Map<String, Object> prefs = new HashMap<String, Object>();
prefs.put("googlegeolocationaccess.enabled", false);
prefs.put("profile.default_content_setting_values.geolocation", 2);
prefs.put("profile.default_content_setting_values.notifications", 1);
prefs.put("profile.managed_default_content_settings", 1);

// 处理下载目录
String downloadDirPath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "test" + File.separator + "resources";
File downloadDir = new File(downloadDirPath);
if (!downloadDir.exists()) {
    downloadDir.mkdirs();
}
prefs.put("download.default_directory", downloadDirPath);

// 新增无头模式下载的关键配置
prefs.put("download.prompt_for_download", false); // 禁止下载弹窗
prefs.put("download.directory_upgrade", true); // 允许替换旧的下载目录
prefs.put("plugins.always_open_pdf_externally", true); // 让Chrome直接下载PDF,而不是在浏览器里打开

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setExperimentalOption("prefs", prefs);
// 添加Ubuntu环境下必须的无头模式参数
chromeOptions.addArguments("--headless=new");
chromeOptions.addArguments("--disable-gpu");
chromeOptions.addArguments("--no-sandbox"); // Ubuntu环境下必须禁用沙箱,否则Chrome启动失败
chromeOptions.addArguments("--disable-dev-shm-usage"); // 解决Ubuntu虚拟机内存不足的问题

3. 等待文件下载完成再读取

Windows本地下载速度快,文件瞬间就存在,但Pipeline的虚拟机可能因为网络或性能问题,下载有延迟——你的代码可能在文件还没下载完就去读取,自然会找不到。

添加等待逻辑:

// 假设你要读取的PDF文件名是MyPdf.pdf
File pdfFile = new File(downloadDirPath + File.separator + "MyPdf.pdf");
int waitSeconds = 0;
int maxWait = 30; // 最多等30秒
while (!pdfFile.exists() && waitSeconds < maxWait) {
    try {
        Thread.sleep(1000); // 每秒检查一次
        waitSeconds++;
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

if (pdfFile.exists()) {
    // 正常读取PDF
    PDDocument document = PDDocument.load(pdfFile);
    // 后续业务逻辑
} else {
    throw new FileNotFoundException("PDF下载超时,未找到文件:" + pdfFile.getAbsolutePath());
}

4. 检查路径大小写问题

Ubuntu是大小写敏感的文件系统,Windows则不是。比如如果实际下载的文件名是mypdf.pdf,但你代码里写的是MyPdf.pdf,就会找不到文件。

验证方法:在Pipeline里加个步骤,打印下载目录的内容,确认文件是否存在以及文件名是否正确:

steps:
  - bash: ls -la src/test/resources/
    displayName: Check download directory content
    condition: always() # 即使测试失败也要执行这个步骤,方便排查

总结

按照上面的步骤依次排查,重点是确保目录存在、配置无头Chrome的下载参数、添加下载等待逻辑——这三个点是解决Azure Pipeline中Selenium下载文件问题的核心方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:10:27