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

Cypress提取Zip归档并验证文件内容报错:fs$readFile is not a function

问题根源分析

这个错误的核心原因是**decompress是Node.js环境下的库,依赖Node核心模块fs,但Cypress的测试代码默认运行在浏览器上下文,浏览器环境中不存在fs模块**。同时未处理的Promise拒绝,是因为你在浏览器环境中调用了依赖Node模块的异步方法,导致Promise无法正常resolve/reject,进而抛出未捕获异常。

解决方案:将解压逻辑移至Node环境执行

Cypress提供了cy.task机制,允许测试代码调用运行在Node环境中的自定义任务。我们可以把文件解压、读取的逻辑放到task中,避开浏览器环境的限制,同时正确处理Promise生命周期。

步骤1:配置Cypress任务(cypress.config.js)

在Cypress配置文件中注册处理解压和文件读取的任务,所有依赖fs、decompress的逻辑都在这里执行:

const { defineConfig } = require("cypress");
const decompress = require('decompress');
const fs = require('fs');
const path = require('path');
const { rmSync } = require('fs');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        async extractAndValidateZip(zipPath) {
          try {
            // 清理旧的解压目录,避免残留文件干扰测试
            const outputDir = path.join(__dirname, 'cypress', 'downloads', 'extracted');
            rmSync(outputDir, { recursive: true, force: true });

            // 解压Zip文件到临时目录
            await decompress(zipPath, outputDir);

            // 读取需要验证的4个文件内容
            const targetFiles = ['file1.txt', 'file2.csv', 'file3.json', 'file4.md'];
            const fileContents = {};

            for (const fileName of targetFiles) {
              const fullPath = path.join(outputDir, fileName);
              fileContents[fileName] = fs.readFileSync(fullPath, 'utf8');
            }

            return fileContents;
          } catch (err) {
            // 主动抛出错误,让Cypress捕获并标记测试失败,避免未处理Promise拒绝
            throw new Error(`解压/读取文件失败: ${err.message}`);
          }
        }
      });
    },
  },
});

步骤2:编写测试用例

在测试代码中调用上述任务,完成登录、下载、验证流程:

describe('Zip文件下载与内容验证', () => {
  it('完成登录、下载Zip并验证文件内容', () => {
    // 1. 登录操作
    cy.visit('/login');
    cy.get('#username').type('你的用户名');
    cy.get('#password').type('你的密码');
    cy.get('[data-test="login-btn"]').click();
    cy.url().should('include', '/dashboard');

    // 2. 触发Zip下载并等待完成
    cy.get('[data-test="download-zip-btn"]').click();
    const zipFilePath = 'cypress/downloads/archive.zip';
    cy.readFile(zipFilePath, { timeout: 10000 }).should('exist');

    // 3. 调用Node环境的任务解压并读取文件
    cy.task('extractAndValidateZip', zipFilePath).then((fileContents) => {
      // 4. 逐个验证文件内容
      expect(fileContents['file1.txt']).to.include('预期的文本片段');
      expect(fileContents['file2.csv']).to.match(/^ID,Name,Email$/);
      expect(JSON.parse(fileContents['file3.json'])).to.deep.equal({ status: 'success', data: [] });
      expect(fileContents['file4.md']).to.contain('# 归档文件说明');
    });
  });
});
关键注意事项
  • 确保decompress已安装在项目依赖中(执行npm install decompress --save-dev)
  • 测试前确认Cypress的downloads目录存在,或在任务中添加目录创建逻辑
  • 任务中必须处理所有异常并抛出,避免出现未捕获的Promise拒绝
  • 可根据实际需求调整目标文件名、解压路径和内容验证规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:33:33