vue-test-utils调用shallowMount/mount后出现内存泄漏问题求助
Vue Test Utils shallowMount/mount 每次测试后堆内存增加2MB的内存泄漏问题
使用Vue Test Utils的shallowMount或mount方法执行测试时,每次测试后堆内存会稳定增加约2MB,长期运行会导致CI环境内存耗尽。
复现步骤
执行以下命令启动测试:
./node_modules/.bin/jest -- "DummyTest-test.js"
环境版本
- Vue 2.7.10
- Vue Test Utils 1.3.3
- Jest 29.0.3
- Node.js 14.20.0
- @vue/vue2-jest 28.1.0
测试代码
DummyTest-test.js
import { shallowMount } from "@vue/test-utils"; import DummyComponent from "../DummyComponent.vue"; let iterations = [...Array(9999).keys()]; let wrapper; let heap; afterAll(() => { iterations = null; }); afterEach(() => { wrapper.destroy(); wrapper = null; heap = null; }); it.each(iterations)(`Test`, () => { wrapper = shallowMount(DummyComponent); heap = (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2); console.log(`Heap Size: ${heap} MB`); expect(true).toBe(true); });
DummyComponent.vue
<template> <div> <p>Hi</p> </div> </template> <script> export default { name: "DummyComponent", }; </script>
jest.config.js
module.exports = { testEnvironment: "jsdom", transform: { "^.+\\.js$": "babel-jest", "^.+\\.vue$": "@vue/vue2-jest", }, };
预期行为
每次测试迭代后堆内存应保持稳定,无持续增长。
实际行为
每次测试后堆内存增加约2MB,其中0.2MB来自console.log输出,剩余内存泄漏来自组件挂载步骤。
已尝试的解决方案
- 在Vue Test Utils官方仓库提交了相关问题
- 更换Node.js版本(12、16、18),问题未解决
- 测试Vue3+Vue Test Utils v2环境,问题仍存在
- 在
afterEach中调用wrapper.destroy()并置空变量,无效 - 临时使用Jest的
workerIdleMemoryLimit配置限制内存,避免CI崩溃
进一步排查与解决建议
移除console.log减少干扰
先删除测试中的console.log语句,重新运行测试确认内存增长情况。如果日志确实贡献了部分泄漏,可以改用Jest的日志捕获API(如jest.spyOn(console, 'log'))替代直接输出。手动触发垃圾回收
在Node.js环境下添加--expose-gc参数启用手动GC,在afterEach中触发回收,观察内存是否恢复:afterEach(() => { wrapper.destroy(); wrapper = null; heap = null; if (global.gc) global.gc(); });启动命令改为:
node --expose-gc ./node_modules/.bin/jest -- "DummyTest-test.js"单线程运行测试
使用Jest的--runInBand参数强制单线程执行测试,排查是否为多worker进程管理导致的内存泄漏:./node_modules/.bin/jest --runInBand -- "DummyTest-test.js"升级依赖版本
尝试升级Vue Test Utils到1.x分支的最新版本,以及@vue/vue2-jest到对应兼容版本,看是否有官方修复的内存泄漏问题。内存快照分析
使用Chrome DevTools捕获堆快照定位泄漏点:node --inspect ./node_modules/.bin/jest --runInBand -- "DummyTest-test.js"在Chrome中打开
chrome://inspect连接调试,对比每次测试前后的堆快照,找出未被回收的对象及其保留路径。增强清理逻辑
除了wrapper.destroy(),手动清理全局资源:afterEach(() => { wrapper.destroy(); // 清理Vue全局混入 Vue.config.globalMixins = []; // 清空DOM中的测试元素 document.body.innerHTML = ''; wrapper = null; heap = null; });
内容的提问来源于stack exchange,提问作者CaptainFalcoGX
相关产品推荐
相关产品推荐

