使用adm-zip与Cypress验证Zip文件时遭遇内存溢出错误
解决Cypress+adm-zip验证Zip文件的内存溢出问题及验证需求实现
问题概述
使用Cypress v12.8.1 + adm-zip v0.5.10验证Zip文件时出现内存溢出,需完成两项验证:
- a) 验证Zip内文件数量
- b) 验证Zip内文件类型(仅允许
.txt/.pdf/.ppt/.docx)
内存溢出原因及解决
内存溢出主要来自两个点:
- 用
cy.readFile读取整个二进制Zip文件,大文件会占用浏览器进程大量内存 AdmZip默认加载整个Zip内容到内存,大文件易触发内存限制
1. 替换文件下载完成的检查逻辑
放弃cy.readFile读取整个文件,改用Node层监听文件大小变化,确认下载完成:
修改helperFunctions.js:
import path from 'path'; class HelperFunctions { validateZip () { const downloadsFolder = Cypress.config('downloadsFolder') const downloadedFilename = path.join(downloadsFolder, 'ComprehensionStrategyTeachingResourcePackSummarisingZipFile.zip') // 通过Node层检查文件大小稳定,确认下载完成 cy.task('waitForZipDownload', downloadedFilename, { timeout: 35000 }).should('equal', true) // 执行Zip验证任务 cy.task('validateZipFile', downloadedFilename).should('equal', true) } } export default HelperFunctions;
2. 优化adm-zip内存使用+完成验证逻辑
在Node进程(Cypress Task)中处理Zip验证,避免占用浏览器内存;同时仅读取文件元数据(不提取内容),减少内存消耗,并完成两项验证:
修改cypress.config.js:
const AdmZip = require("adm-zip"); const fs = require('fs'); const path = require('path'); const { defineConfig } = require('cypress') module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { on("task", { // 等待文件下载完成的任务 waitForZipDownload: (filename) => { return new Promise((resolve, reject) => { let previousSize = -1; const maxAttempts = 35; // 对应35秒超时 let attempts = 0; const checkFile = () => { attempts++; fs.stat(filename, (err, stats) => { if (err) { if (attempts >= maxAttempts) { reject(new Error(`文件下载超时:${filename}`)); return; } setTimeout(checkFile, 1000); return; } if (stats.size === previousSize) { resolve(true); } else { previousSize = stats.size; if (attempts >= maxAttempts) { reject(new Error(`文件下载超时,大小仍在变化:${filename}`)); return; } setTimeout(checkFile, 1000); } }); }; checkFile(); }); }, // Zip验证任务 validateZipFile: (filename) => { return validateZipFile(filename); }, }); return config; }, baseUrl: "https://staging-qa.someurl.com/", specPattern: "cypress/e2e/**/*.spec.{js,jsx,ts,tsx}", }, }) function validateZipFile (filename) { console.log('开始验证Zip文件:', filename) const zip = new AdmZip(filename); // 过滤文件夹,仅保留文件条目 const zipEntries = zip.getEntries().filter(entry => !entry.isDirectory); // 验证a) 文件数量(替换为你的预期值) const expectedFileCount = 3; // 示例值,根据实际需求修改 if (zipEntries.length !== expectedFileCount) { throw new Error(`文件数量验证失败:预期${expectedFileCount}个,实际${zipEntries.length}个`); } // 验证b) 文件类型 const allowedExtensions = ['.txt', '.pdf', '.ppt', '.docx']; const invalidFiles = zipEntries.filter(entry => { const fileExt = path.extname(entry.entryName).toLowerCase(); return !allowedExtensions.includes(fileExt); }); if (invalidFiles.length > 0) { const invalidNames = invalidFiles.map(f => f.entryName).join(', '); throw new Error(`文件类型验证失败:存在不允许的文件类型 ${invalidNames}`); } console.log('Zip文件验证通过'); return true; }
3. (可选)增大Node进程内存限制
如果Zip文件特别大(>500MB),可在启动Cypress时增加Node内存限制:
NODE_OPTIONS="--max-old-space-size=4096" npx cypress run
测试代码保留
test.spec.js无需修改,保持原有逻辑即可:
import HelperFunctions from "../../../support/helperFunctions"; const helperFunctions = new HelperFunctions(); it('Download test', function () { cy.get('button[type="submit"]').contains("Download").click({force:true}); helperFunctions.validateZip(); })
内容的提问来源于stack exchange,提问作者soccerway
相关产品推荐
相关产品推荐

