I'm using Jest as a testing library and inside its setup hook (which is executed before all my tests), I spawn a child process which launches a testing server on a certain port. The setup code basically executes an NPM command:
"run-server-test": "NODE_ENV=test SERVER_PORT=3001 node src/index.js &",
"test": "NODE_ENV=test SERVER_PORT=3001 jest --detectOpenHandles --forceExit",
And this is the setup function:
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()))
})
})
}
Notice that I execute the command in background with &
. When Jest finishes its job, I notice with ps
that its PID it's different from the one shown in the shell. Without executing it in the background, I get an extra process, the shell's one (/bin/sh
).
How could I get the real PID of that process?
Is there a best way to kill the process launched inside that function?
Thanks!
My current approach is the following:
httpServer
instance used to make the server listen to requests. This is a good case for beforeAll
hook.afterAll
.Another alternative (a bit tricky), could be to launch the server once at the beginning of all your tests and close it at the end:
npm
process.kill(PID, "SIGTERM")