简体   繁体   English

设置 Express 服务器时 NodeJs Testrunner 冻结/停止

[英]NodeJs Testrunner freezes / stops when setting up Express server

I'm using Node v18 with the experimental testrunner.我将 Node v18 与实验性测试运行程序一起使用。 I use express as a dev dependency for http integration tests which works fine but there is one test freezing or stopping the testrunner ( it doesn't continue )我使用 express 作为 http 集成测试的开发依赖项,它工作正常,但有一个测试冻结或停止测试运行程序(它不会继续)

I'm using TS but can also reproduce it with JS, the test file HttpTests.js contains我用的是 TS 但也可以用 JS 重现,测试文件HttpTests.js包含

import assert from 'assert/strict';
import express from 'express';
import test from 'node:test';

test('Http', async () => {
  const server = express();
    
  server.listen(3000);
  assert.ok(false);
});

Running this with the npm script "test": "node --test $(find. -name '*Tests.js')" breaks the test runner.使用 npm 脚本"test": "node --test $(find. -name '*Tests.js')"会破坏测试运行器。

Any ideas what is wrong or missing?任何想法有什么问题或缺失?


Why am I not using the default execution model ?为什么我不使用默认执行 model

Since I'm using TS I had to find a way to use ts-node with the testrunner.由于我使用的是 TS,因此我必须找到一种将 ts-node 与 testrunner 一起使用的方法。 You can find more information here您可以在这里找到更多信息

https://github.com/nodejs/node/issues/43675 https://github.com/nodejs/node/issues/43675

So currently my TS project is using this npm script, which works fine所以目前我的 TS 项目正在使用这个npm 脚本,它工作正常


Reproduction再生产

I created a minimal reproduction repository with and without TypeScript我创建了一个最小的复制存储库,有和没有 TypeScript

For reproduction purposes run mkdir reproduction && cd reproduction && npm init -y && npm install express .出于复制目的,运行mkdir reproduction && cd reproduction && npm init -y && npm install express After that create a test directory with a file HttpTests.js containing the content as shown above.之后,使用包含如上所示内容的文件HttpTests.js创建一个测试目录。 Change the package.json topackage.json更改为

{
  "name": "reproduction",
  "type": "module",
  "scripts": {
    "test": "node --test $(find . -name '*Tests.js')"
  }
}

and run the script, the testrunner should not finish.并运行脚本,testrunner 不应该完成。


The testrunner is still experimental测试运行器仍处于试验阶段

Yes I know.是的,我知道。 But there are many tests in the project that work perfectly fine.但是该项目中有许多测试工作得非常好。 Some sample code一些示例代码

await t.test('subtest - saves data.', async () => {
    const expectedResult = {};
  
    const api = express();
    const port = await getRandomPort();
    const server = api
        .use(express.json())
        .post('/save', (request, response) => {
            response.json(expectedResult);
        })
        .listen(port);

    const httpDataProvider = new HttpDataProvider({ url: `http://localhost:${port}` });
    const actualResult = await httpDataProvider.saveSomething();

    assert.deepEqual(actualResult, expectedResult);

    server.close();
});

The issue is the async activity that you start ( server.listen() ) but don't stop before the test errors out (by an exception thrown by assert.ok(false) ).问题是您启动的异步活动( server.listen() )但在测试错误出现之前不停止(由assert.ok(false)引发的异常)。

Your second test case will probably also stall if actualResult doesn't deep-equal expectedResult because of the same issue ( server.close() won't be called).如果由于相同的问题(不会调用actualResult server.close()实际结果不等于expectedResult结果,您的第二个测试用例也可能会停止。

A workaround would be to always make sure the server gets closed in the end:一种解决方法是始终确保服务器最终关闭:

test('Http', async () => {
  const app    = express();
  const server = app.listen(3000);
  try {
    assert.ok(false);
  } finally {
    server.close();
  }
});

Most test frameworks provide "before/after" functionality that can be used to set up or tear down auxiliary objects before and after a test.大多数测试框架提供“之前/之后”功能,可用于在测试之前和之后设置或拆除辅助对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM