开玩笑地测试多个测试文件端口3000已在使用中

bti*_*sae 3 mongoose node.js express supertest jestjs

我正在为我的Express应用创建测试。该项目有多个测试文件。在每个模块中,需要在beforeEach()方法中使用服务器实例,并在afterEach()方法中关闭服务器实例。但是在测试了其中一个或两个模块之后,它将提高已经使用的地址,并且玩笑不会终止。

beforeEach(() =>  {

    server = require('./../../../bin/www')});
afterEach(async() => { 
    server.close();
    /**
     * database cleanup logic goes here.
     */

 });
Run Code Online (Sandbox Code Playgroud)

我想在所有测试套件完成后终止玩笑。

J. *_*son 23

默认情况下只并行运行测试套件。但是,运行测试的机器只有一个端口 3000(或端口 4000 等)。

这意味着如果你告诉你的应用程序监听一个端口,然后启动多个并发进程,将会发生端口冲突并且 Jest 将退出EADDRINUSE - port already in use

就像已经提到的某些人一样,您可以通过使用--runInBand. 但是,您将失去并行化的性能优势。

还有另一种方法......在运行测试时不要显式监听端口。

if (process.env.NODE_ENV !== 'test') {
  app.listen(port, () => console.log(`Listening on port ${port}`)
}
Run Code Online (Sandbox Code Playgroud)

现在,当您将应用程序提供给 supertest 时,它将在端口 0 上运行您的应用程序,因为它尚未在端口上运行。

const app = require('../app')
const request = require('supertest')

it('gets todos', async () => {
  const response = await request(app).get('/todos')
  expect(response.body.length).toEqual(3)
}
Run Code Online (Sandbox Code Playgroud)

你问的端口 0 到底是什么?这就是你告诉Unix机器的方式......

选择您找到的第一个随机可用端口。

现在每个测试套件都在一个随机可用的端口上运行,不再有端口冲突的风险,这意味着我们已经解决了EADDRINUSE - port already in use错误,我们可以继续并行运行测试。


小智 17

最基本的事情是将你的 app.listen() 放入其他文件中,而不是包含所有路由的文件。例如:index.js

const express = require("express");
const app = express();
const bodyParser = require("body-parser");

app.use(bodyParser.json());

const students = ["Elie", "Matt", "Joel", "Michael"];

app.get("/", (req, res) => {
  return res.json(students);
});

module.exports = app;
Run Code Online (Sandbox Code Playgroud)

和服务器.js

const app = require("./index");

app.listen(3000, () => console.log("server starting on port 3000!"));
Run Code Online (Sandbox Code Playgroud)

这样 Jest 将根本不会读取 app.listen() 。干杯!


Joh*_*bes 6

我遇到了这个问题,并且似乎通过设置开玩笑只使用一个工作程序解决了该问题。我认为问题是由多个使用同一端口运行的服务器实例引起的,从而导致了冲突。

这是我的npm package.json文件中的行。在--maxWorkers=1似乎做的伎俩(https://jestjs.io/docs/en/cli#maxworkers-num-string)。

"scripts": {
  "test": "jest --forceExit --detectOpenHandles  --watchAll --maxWorkers=1"
},
Run Code Online (Sandbox Code Playgroud)


Ser*_*are 6

我正在使用节点表达服务器4.16.2。如果您使用的是其他版本,这可能不适用于您。当您关闭服务器时,在您的描述块中await

describe('auth midleware', () => {
        // loading the server
        beforeEach(() => {>         
            server = require('../../../index')
        });

        // closing the server
        afterEach(async () => {
            await server.close();        
        });


        // the tests will go here
    });
Run Code Online (Sandbox Code Playgroud)

此外,执行此操作后,请在命令行中运行节点应用程序。

node index.js
Run Code Online (Sandbox Code Playgroud)

检查你的 package.json,你的脚本测试标签是如何命名的。我的是测试。

{ ...
      "scripts": {
        "test": "jest --verbose --coverage --forceExit --watchAll --maxWorkers=1"
      }
      ...
    }
Run Code Online (Sandbox Code Playgroud)

之后再次运行测试。

npm test  
Run Code Online (Sandbox Code Playgroud)