I want to run set of test scripts using NodeJS, It outputs test results while executing. I want these different tests scripts to run synchronously and also output the results while execution.
I tried using the spawnSync() function of child process, however it doesn't output data during execution of the command.
const { spawnSync } = require("child_process")
const cmd = spawnSync('./gradlew',['test'],{cwd : '../../../'})
console.log(`Output: ${cmd.stdout}`)
The above code outputs the results only when the task has fully completed execution. I believe this is the expected behavior of spawnSync.
Therefore i tried running spawn() inside an async function with await to synchronize it, I'm not sure whether this approach is correct.
const { spawn } = require("child_process")
const cmd = spawn('./gradlew',['test'],{cwd : '../../../'})
const cmd1 = spawn('./gradlew',['test'],{cwd : '../../../'})
async function runFeature(){
console.log("Running feature....")
cmd.stdout.on('data', (data) => {
console.log(`Output: ${data}`);
});
}
async function runFeature1(){
console.log("Running feature 1....")
cmd1.stdout.on('data', (data) => {
console.log(`Output1: ${data}`);
});
}
async function main(){
try{
console.log("Starting...")
await runFeature()
await runFeature1()
process.exit(0)
} catch(e){
console.error(e)
process.exit(1)
}
}
main()
When running the above code, the command ends without any output as follows. It looks like the cmd.stdout.on()
method is not getting executed.
harrym@HarryM:~/Project/test$ node run-test.js
Starting..
Running feature....
Running feature 1....
harrym@HarryM:~/Project/test$
Is there anything wrong in this way of approach?. I really need help in debugging this issue. In addition any suggestions to synchronize a child process while outputting live data stream would be highly appreciated.
Thank you in advance :)
If you use node 10 or above, you can use generic iterator function like that:
const { spawn } = require('child_process');
(async () => {
try {
const lsSpawn = spawn('ls', ['-l'], { cwd: '../../../' });
let error = '';
for await (const chunk of lsSpawn.stderr) {
error += chunk;
}
if (error) {
console.error('error', error);
return;
}
let data = '';
for await (const chunk of lsSpawn.stdout) {
data += chunk;
}
if (data) {
console.log('data', data);
}
} catch (e) {
console.error('execute error', e);
}
})();
I use for await
in lsSpawn.stderr
and lsSpawn.stdout
Tip: If you wanna use promise don't mix-up with event.on
, you should convert event.on
to promise format