diff --git a/test/common/test-error-reporter.js b/test/common/test-error-reporter.js index 3098b10885f19d..fed92d9776c8a8 100644 --- a/test/common/test-error-reporter.js +++ b/test/common/test-error-reporter.js @@ -30,6 +30,12 @@ module.exports = async function* errorReporter(source) { output.push(inspect(error)); output.push('\n'); yield output.join('\n'); + + if (process.env.FAIL_FAST) { + yield `\n\u001b[31m✖ Bailing on failed test: ${event.data.name}\u001b[0m\n`; + process.exitCode = 1; + process.emit('SIGINT'); + } } } }; diff --git a/test/fixtures/test-runner/error-reporter-fail-fast/a.mjs b/test/fixtures/test-runner/error-reporter-fail-fast/a.mjs new file mode 100644 index 00000000000000..6508394bbc682d --- /dev/null +++ b/test/fixtures/test-runner/error-reporter-fail-fast/a.mjs @@ -0,0 +1,6 @@ +const assert = require('node:assert'); +const { test } = require('node:test'); + +test('fail', () => { + assert.fail('a.mjs fail'); +}); diff --git a/test/fixtures/test-runner/error-reporter-fail-fast/b.mjs b/test/fixtures/test-runner/error-reporter-fail-fast/b.mjs new file mode 100644 index 00000000000000..87abd62db2773f --- /dev/null +++ b/test/fixtures/test-runner/error-reporter-fail-fast/b.mjs @@ -0,0 +1,6 @@ +const assert = require('node:assert'); +const { test } = require('node:test'); + +test('fail', () => { + assert.fail('b.mjs fail'); +}); diff --git a/test/parallel/test-runner-error-reporter.js b/test/parallel/test-runner-error-reporter.js new file mode 100644 index 00000000000000..2afe6f7cd4c7f5 --- /dev/null +++ b/test/parallel/test-runner-error-reporter.js @@ -0,0 +1,32 @@ +'use strict'; + +const fixtures = require('../common/fixtures'); +const assert = require('node:assert'); +const { spawnSync } = require('node:child_process'); +const { test } = require('node:test'); +const cwd = fixtures.path('test-runner', 'error-reporter-fail-fast'); +const env = { ...process.env }; + +test('all tests failures reported without FAIL_FAST flag', async () => { + const args = [ + '--test-reporter=./test/common/test-error-reporter.js', + '--test-concurrency=1', + '--test', + `${cwd}/*.mjs`, + ]; + const cp = spawnSync(process.execPath, args, { env }); + const failureCount = (cp.stdout.toString().match(/Test failure:/g) || []).length; + assert.strictEqual(failureCount, 2, 'Expected two test failures without FAIL_FAST'); +}); + +test('FAIL_FAST stops test execution after first failure', async () => { + const args = [ + '--test-reporter=./test/common/test-error-reporter.js', + '--test-concurrency=1', + '--test', + `${cwd}/*.mjs`, + ]; + const cp = spawnSync(process.execPath, args, { env: { ...env, FAIL_FAST: 'true' } }); + const failureCount = (cp.stdout.toString().match(/Test failure:/g) || []).length; + assert.strictEqual(failureCount, 1, 'Expected one test failure with FAIL_FAST'); +});