Reputation: 1230
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!
Upvotes: 3
Views: 4587
Reputation: 1230
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")
Upvotes: 3
Reputation: 17203
You can create a start and stop method on your sever. Then you don't need to worry about forking your processes.
I'm using express as an example.
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);
});
Upvotes: 1