在我的 Express.js Jest 测试中找不到内存泄漏

2024-02-07

我现在花了一些时间尝试在 Jest 测试中查找内存泄漏,尽管我已经成功解决了一些问题,但仍然有相当多的内存在测试套件之间泄漏。具体来说,当我npm test(所有测试套件),我得到以下输出:

PASS  src/.../suite1.test.ts (71.154 s, 163 MB heap size)
PASS  src/.../suite2.test.ts (59.809 s, 229 MB heap size)
PASS  src/.../suite3.test.ts (9.838 s, 231 MB heap size)
PASS  src/.../suite4.test.ts (7.696 s, 242 MB heap size)
FAIL  src/.../suite5.test.ts (251 MB heap size)
PASS  src/.../suite6.test.ts (10.825 s, 318 MB heap size)
PASS  src/.../suite7.test.ts (19.679 s, 363 MB heap size)
PASS  src/.../suite8.test.ts (14.128 s, 408 MB heap size)
PASS  src/.../suite9.test.ts (16.89 s, 452 MB heap size)

从上面的输出来看,测试套件完成后似乎仍有一些东西仍然存在。到底是什么困扰着我!内存泄漏似乎也可能在所有测试套件之间共享,因为每个套件都比上一个套件留下了更多的内存堆大小。

这是我所有测试套件的共享测试结构:

import request from "supertest";
import app from "../../app";
import mongoose from "mongoose";
...
some models that I need for testing
...
import faker from "faker";
import eventEmitter from "../../loaders/eventEmitter";

jest.mock("../../some-module");
jest.mock("../../another-module");
jest.mock("axios", () => {
  // Require the original module to not be mocked...
  const originalModule = jest.requireActual("axios");

  return {
    ...originalModule,
    post: jest.fn().mockReturnValue({ data: { access_token: 123, expires_in: 600000 } })
  };
});

describe("TestSuite1", () => {
  beforeEach(() => jest.clearAllMocks());
  beforeAll(async () => await connectDb("TestSuite1"));
  afterEach(async () => await clearDb()); // Function that deletes collections from Mongo
  afterAll(async () => {
    await mongoose.connection.dropDatabase();
    await mongoose.connection.close();
  });

  describe("POST /some-endpoint") {
    beforeEach(async () => {
      myDocument = await buildDocument(); // Builds and saves() to Mongo some document
    });

    it("some assertion", async () => {
      const response = await request(app)
        .post("some-endpoint")
        .send(some-data)
        .set("Accept", "application/json");

      expect(response.status).toEqual(204);
      // more assertions on the response
    });
  }

这里有什么显而易见的事情吗?如果需要,我可以添加更多代码。

Edit:当我使用 --detectOpenHandles 运行测试时,我也会收到此错误;这可能相关吗?

  ●  TCPSERVERWRAP

      108 |         it("some assertion", async () => {
      109 |           const response = await request(app)
    > 110 |             .post("some-endpoint")
          |              ^
      111 |             .send({})
      112 |             .set("some-header", header-value)
      113 |             .set("Accept", "application/json");

Edit 2:我尝试在测试套件之后关闭服务器,添加以下内容:

let server: http.Server;
let agent: SuperAgentTest;

beforeAll(async () => {
  await connectDb("TestSuite1");
  server = app.listen(4000, () => {
    agent = request.agent(server);
  });
});
afterAll(async () => {
  await closeDb();
  jest.resetAllMocks();
  server && server.close();
});

这似乎解决了打开句柄问题,但没有解决内存泄漏问题。

另外,为了清楚起见,eventEmitter导入的模块执行以下操作:

const eventEmitter = new EventEmitter();
export default eventEmitter;

让我们试着稍微分析一下:

  • 您会看到堆大小随着时间的推移而增加。
  • 测试前后发生的唯一可能存在泄漏的事情是连接到数据库,但您在最后终止了连接,所以这不是问题。
  • 您在评论中提到了如何处理 buildDocument ,它似乎并不影响泄漏本身。

看看你的代码,我无法立即识别问题(这是我很久以前也遇到过的问题,但没有深入研究)。

我想了一下,在我看来,唯一的另一种可能性是——这不是你的错,可能是笑话的垃圾收集的问题。

对此已有讨论https://github.com/facebook/jest/issues/7874 https://github.com/facebook/jest/issues/7874.

我建议运行测试--runInBand查看有/没有它的统计数据(即jest --logHeapUsage --runInBand).

此外,如上述问题的解决方法所示,请尝试使用以下命令公开垃圾收集器--expose-gc并添加

afterAll(() => {
  global.gc && global.gc()
})

到通用测试设置以确保强制垃圾收集。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在我的 Express.js Jest 测试中找不到内存泄漏 的相关文章

随机推荐

  • 如何在canvas对象上使用jquery uidraggable方法?

    我试图允许用户使用可拖动方法在画布元素周围移动矩形 这是我最初的想法 但行不通 我有一个小提琴设置在http jsfiddle net r2Zbe http jsfiddle net r2Zbe button click function
  • 为 Google 电子表格授权脚本会出现错误 401 returned_client

    我刚刚制作了一个简单的脚本来自动为我的谷歌电子表格复制和粘贴一些数据 但是 当我尝试运行脚本以授予授权时 我会看到正常的弹出窗口 但是当我 查看权限 时 我收到了以前从未见过的错误 通常我只是弹出我的谷歌帐户的身份验证 你认为这是为什么 任
  • Scala 中可以为 null 吗?

    我刚刚读过这个问题 https stackoverflow com questions 9853645 并偶然发现了以下引用 斯卡拉款待 就好像它在类中定义如下Any final def that Any Boolean if null e
  • 物化模式不起作用

    我为物化模式编写了一个简单的代码 HTML 代码 a class waves effect waves light btn view View Scores a div class modal div class modal content
  • 升级到 1.6 后,为什么“添加另一个”按钮从我的 django 内联中消失了?

    我有一个 Django 网站 管理界面中有很多内联内容 在我使用的以前版本的 django 上 有一个 添加另一个 按钮来添加更多条目 我升级到 django 1 6 这个按钮消失了 这是我的 admin py 的相关部分 class My
  • 如何在 Laravel 中插入数据库之前验证图像尺寸

    我是 laravel 的新手 im 尝试验证图像的尺寸 我想要尺寸最小 宽度 100 高度 50 iam 在controller php 中使用验证代码在这里 galimg gt 必需 最大 200kb DimensionMin 300 3
  • html 未在 wamp 中解析为 php

    我在 htaccess 文件中使用此代码片段将 html 解析为 php
  • 如何在Eclipse中支持UTF-8编码

    如何在 eclipse 中添加 UTF 8 支持 我想添加例如俄语 但 eclipse 不支持它 我应该怎么办 请指导我 Try this 1 Window gt Preferences gt General gt Content Type
  • LINQ 是对象关系映射器吗?

    LINQ 是一种对象关系映射器吗 LINQ 本身是一组语言扩展 可帮助查询 提高可读性并减少代码 LINQ to SQL 是一种 OR 映射器 但它并不是特别强大 这实体框架 http msdn microsoft com en us li
  • 警告“导入的库具有相同的名称,但它们不具有相同的名称”

    我在类中有以下导入语句 import package dart web toolkit ui dart import util flex table builder dart as ftBldr import factors list vi
  • 在 C++ 中创建 setter 函数的最佳方法

    我想编写一个通过移动或复制接收参数的模板函数 我使用的最有效的方法是 void setA A a m a std move a 在这里 当我们使用的是 A a setA a lt lt one copy ctor one move ctor
  • 包含 boost/Optional.hpp 时出现 C2143 语法错误

    我遇到了一个我无法理解的编译时错误 我尝试使用boost optional在我的代码中 一旦我包含boost optional hpp我无法再构建我的项目了 如果我注释掉这个 include 语句 它就会起作用 我什至没有任何实际用途boo
  • 如何在 bash 中不使用 printf 将字符转换为 ASCII

    ascii printf d 1 我目前正在使用此函数将字符转换为 ASCII 但是我只想将函数的结果存储为变量而不打印 ascii 我该怎么办呢 请记住 我总共只使用了几个小时的 bash 如果这是一个愚蠢的问题 我很抱歉 在 bash
  • 如何解决此 RCurl 错误:“SSL 证书问题:证书已过期”?

    我只是想获得下面一个简单的 URL 响应 但出现以下错误 该网站是有效的 我过去已经可以从该网站提取数千次信息 jsonString lt getURL full url Error in function type msg asError
  • 如何限制对ravendb管理面板的访问?

    当默认情况下运行 Raven Server exe 时 管理面板在 IP PORT 地址处可见 如何限制仅特定用户访问此面板 Steve 我们将 RavenDB 作为 Windows 服务运行 并使用 Windows 身份验证来控制访问 如
  • 将画布保存到图像文件会保存空白黑色图像

    首先 我对 UWP 和 XAML 还很陌生 我在我的 uwp 上编写了一个简单的代码 其中有一个画布 命名为 ImageHolder 里面有一个图像和文本块 我的主要问题是 每当我尝试使用 RenderTargetBitmap 将画布保存到
  • 如何在git的post-receive钩子中处理分支上的文件

    我有一个远程服务器 我在上面创建了一个裸 git 存储库 我想创建一个钩子 以便给定的脚本在任何给定分支上收到的最新代码上运行 我知道post receive可以使用钩子来实现它 但是我想做以下事情 找到收到代码的分支 在临时位置检出代码并
  • Python:交织两个列表[重复]

    这个问题在这里已经有答案了 执行以下操作的 pythonic 方法是什么 我有两个清单a and b相同长度的n 我想形成一个列表 c a 0 b 0 a 1 b 1 a n 1 b n 1 c item for pair in zip a
  • jQuery / JavaScript 中的自定义滚动条数学

    我目前正在开发一个项目 该项目使用自定义滚动插件 由我编写 来允许元素在触摸设备以及桌面浏览器中滚动 一切都工作正常 包括 iOS 的速度和减速度 然而 剩下的唯一问题是当用户滚动时计算滚动条的顶部 或左侧 位置 我用以下公式计算了滚动条的
  • 在我的 Express.js Jest 测试中找不到内存泄漏

    我现在花了一些时间尝试在 Jest 测试中查找内存泄漏 尽管我已经成功解决了一些问题 但仍然有相当多的内存在测试套件之间泄漏 具体来说 当我npm test 所有测试套件 我得到以下输出 PASS src suite1 test ts 71