-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
test: Run node integration tests in isolation #5721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b0b65c7
e4b7631
b86bdb7
dd5fe3f
8028d9e
d697937
cc38145
4aee3fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/* eslint-disable no-console */ | ||
import childProcess from 'child_process'; | ||
import os from 'os'; | ||
|
||
// This variable will act as a job queue that is consumed by a number of worker threads. Each item represents a test to run. | ||
const testPaths = childProcess.execSync('jest --listTests', { encoding: 'utf8' }).trim().split('\n'); | ||
|
||
const numTests = testPaths.length; | ||
const fails: string[] = []; | ||
|
||
// We're creating a worker for each CPU core. | ||
const workers = os.cpus().map(async (_, i) => { | ||
while (testPaths.length > 0) { | ||
const testPath = testPaths.pop(); | ||
console.log(`(Worker ${i}) Running test "${testPath}"`); | ||
await new Promise(resolve => { | ||
const jestProcess = childProcess.spawn('jest', ['--runTestsByPath', testPath as string, '--forceExit']); | ||
|
||
// We're collecting the output and logging it all at once instead of inheriting stdout and stderr, so that | ||
// test outputs of the individual workers aren't interwoven, in case they print at the same time. | ||
let output = ''; | ||
|
||
jestProcess.stdout.on('data', (data: Buffer) => { | ||
output = output + data.toString(); | ||
}); | ||
|
||
jestProcess.stderr.on('data', (data: Buffer) => { | ||
output = output + data.toString(); | ||
}); | ||
Comment on lines
+21
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you doing it this way (rather than just setting |
||
|
||
jestProcess.on('error', error => { | ||
console.log(output); | ||
console.log(`(Worker ${i}) Error in test "${testPath}"`, error); | ||
fails.push(`FAILED: "${testPath}"`); | ||
resolve(); | ||
}); | ||
|
||
jestProcess.on('exit', exitcode => { | ||
console.log(`(Worker ${i}) Finished test "${testPath}"`); | ||
console.log(output); | ||
if (exitcode !== 0) { | ||
fails.push(`FAILED: "${testPath}"`); | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
}); | ||
|
||
void Promise.all(workers).then(() => { | ||
console.log('-------------------'); | ||
console.log(`Successfully ran ${numTests} tests.`); | ||
if (fails.length > 0) { | ||
console.log('Not all tests succeeded:\n'); | ||
fails.forEach(fail => { | ||
console.log(`● ${fail}`); | ||
}); | ||
process.exit(1); | ||
} else { | ||
console.log('All tests succeeded.'); | ||
process.exit(0); | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having an explanation here is both helpful in its own right and possibly a way to forestall other folks asking the same question Abhi asked about
foreEach
.Also:
TIL! 🙂