Skip to content

chore(node-integration-tests): Improve local testing experience #8714

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

Merged
merged 2 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/node-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"mongodb-memory-server-global": "^7.6.3",
"mysql": "^2.18.1",
"nock": "^13.1.0",
"pg": "^8.7.3"
"pg": "^8.7.3",
"yargs": "^16.2.0"
},
"config": {
"mongodbMemoryServer": {
Expand Down
42 changes: 41 additions & 1 deletion packages/node-integration-tests/utils/run-tests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
/* eslint-disable no-console */
import childProcess from 'child_process';
import os from 'os';
import yargs from 'yargs';

const args = yargs
.option('t', {
alias: 'testNamePattern',
type: 'string',
description: 'Filter for a specific test spec\nsee: https://jestjs.io/docs/cli#--testnamepatternregex',
})
.option('watch', {
type: 'boolean',
description: 'Run tests in watch mode\nsee: https://jestjs.io/docs/cli#--watch',
}).argv;

// 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');
Expand All @@ -14,7 +26,17 @@ const workers = os.cpus().map(async (_, i) => {
const testPath = testPaths.pop();
console.log(`(Worker ${i}) Running test "${testPath}"`);
await new Promise<void>(resolve => {
const jestProcess = childProcess.spawn('jest', ['--runTestsByPath', testPath as string, '--forceExit']);
const jestArgs = ['--runTestsByPath', testPath as string, '--forceExit'];

if (args.t) {
jestArgs.push('-t', args.t);
}

if (args.watch) {
jestArgs.push('--watch');
}

const jestProcess = childProcess.spawn('jest', jestArgs);

// 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.
Expand All @@ -36,6 +58,7 @@ const workers = os.cpus().map(async (_, i) => {
});

jestProcess.on('exit', exitcode => {
output = checkSkippedAllTests(output, i, testPath);
console.log(`(Worker ${i}) Finished test "${testPath}"`);
console.log(output);
if (exitcode !== 0) {
Expand All @@ -61,3 +84,20 @@ void Promise.all(workers).then(() => {
process.exit(0);
}
});

/**
* Suppress jest output for test suites where all tests were skipped.
* This only clutters the logs and we can safely print a one-liner instead.
*/
function checkSkippedAllTests(output: string, workerNumber: number, testPath: string | undefined): string {
const regex = /Tests:\s+(\d+) skipped, (\d+) total/gm;
const matches = regex.exec(output);
if (matches) {
const skipped = Number(matches[1]);
const total = Number(matches[2]);
if (!isNaN(skipped) && !isNaN(total) && total === skipped) {
return `(Worker ${workerNumber}) > Skipped all (${total} tests) in ${testPath}`;
}
}
return output;
}