Убить сервер node.js (запущенный в хуке настройки jest) в jest teardown - PullRequest
0 голосов
/ 21 марта 2019

Я использую Jest в качестве библиотеки тестирования и внутри установочного хука (который выполняется перед всеми моими тестами), я spawn дочерний процесс который запускает тестовый сервер на определенном порту. Код установки в основном выполняет команду NPM:

"run-server-test": "NODE_ENV=test SERVER_PORT=3001 node src/index.js &",
"test": "NODE_ENV=test SERVER_PORT=3001 jest --detectOpenHandles --forceExit",

А это функция настройки:

const { spawn } = require("child_process")

module.exports = async function setup() {
  return new Promise((resolve, reject) => {
    const testServerProcess = spawn("npm", ["run", "run-server-test"])

    testServerProcess.on("error", err => {
      console.log("Failed to start subprocess.", err)
      reject(err)
    })

    testServerProcess.stdout.on("data", data => {
      if (data.toString().startsWith("Apollo Server")) {
        console.log(`\nTest server running with PID ${testServerProcess.pid}`)
        resolve(true)
      }
    })

    testServerProcess.stderr.on("data", data => {
      console.error(`stderr: ${data}`)
      reject(new Error(data.toString()))
    })
  })
}

Обратите внимание, что я выполняю команду в фоновом режиме с &. Когда Jest заканчивает свою работу, я отмечаю ps, что его PID отличается от показанного в оболочке. Не выполняя его в фоновом режиме, я получаю дополнительный процесс - оболочку (/bin/sh). Как я могу получить реальный PID этого процесса? Есть ли лучший способ убить процесс, запущенный внутри этой функции? Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 марта 2019

@ Ответ VtoCorleone может быть хорошим, если у вас есть только одна серия тестов, связанных с сервером, но если у вас отличная кодовая база, лучше запустить сервер только один раз, в начале тестов.Я закончил тем, что сделал это:

  • напрямую порождает процесс узла вместо того, чтобы проходить через npm
  • сохранить идентификатор процесса во временной коллекции Монго (но может быть любым)
  • в демонтаже, я получаю PID, а затем просто делаю process.kill(PID, "SIGTERM")
0 голосов
/ 21 марта 2019

Вы можете создать метод запуска и остановки на своем сервере. Тогда вам не нужно беспокоиться о разветвлении ваших процессов.

Я использую экспресс в качестве примера.

app.js

const start = async (callback => { 
  await database.connect();
  server.listen(config.port, config.ip, () => {
    callback();
  });
};

const stop = (callback => {
  server.close(async () => {
    await database.disconnect();
    callback();
  });
};

app.test.js

const server = require('./path/to/server');

beforeAll(async () => {
  try {
    await server.start();
  } catch (error) {
    // if the server doesn't start up or the seeding fails, just
    // exit the process ASAP
    process.exit(1);  
  }
});

afterAll(done => {
  server.stop(done);
});
...