Jest's test runner responsible for orchestrating test execution, managing worker processes, and coordinating parallel test runs
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The main TestRunner class providing both serial and parallel test execution with event-driven progress reporting, worker process coordination, and real-time test status events.
The default export implementing EmittingTestRunner for comprehensive test execution management.
/**
* Main test runner class implementing event-driven test execution
* Supports both serial and parallel execution modes with worker management
*/
export default class TestRunner extends EmittingTestRunner {
constructor(globalConfig: Config.GlobalConfig, context: TestRunnerContext);
/**
* Execute a collection of tests with the specified options
* @param tests - Array of test objects containing path and context
* @param watcher - Test watcher for interrupt handling
* @param options - Execution options including serial mode flag
* @returns Promise that resolves when all tests complete
*/
runTests(
tests: Array<Test>,
watcher: TestWatcher,
options: TestRunnerOptions
): Promise<void>;
/**
* Register event listener for test execution events
* @param eventName - Name of the event to listen for
* @param listener - Function to call when event is emitted
* @returns Unsubscribe function to remove the listener
*/
on<Name extends keyof TestEvents>(
eventName: Name,
listener: (eventData: TestEvents[Name]) => void | Promise<void>
): UnsubscribeFn;
}Usage Examples:
import TestRunner from "jest-runner";
import { TestWatcher } from "jest-watcher";
import type { Test } from "@jest/test-result";
// Create runner with configuration
const runner = new TestRunner(globalConfig, {
changedFiles: new Set(["/changed/file.js"]),
sourcesRelatedToTestsInChangedFiles: new Set(["/source/file.js"])
});
// Set up event listeners
runner.on('test-file-start', ([test]) => {
console.log(`Starting: ${test.path}`);
});
runner.on('test-file-success', ([test, result]) => {
console.log(`✓ ${test.path} - ${result.numPassingTests} tests passed`);
});
runner.on('test-file-failure', ([test, error]) => {
console.error(`✗ ${test.path} failed:`, error.message);
});
// Execute tests in parallel
await runner.runTests(tests, watcher, { serial: false });
// Execute tests serially (useful for debugging)
await runner.runTests(tests, watcher, { serial: true });The runner supports two execution modes with different characteristics and use cases.
Default mode that executes tests across multiple worker processes for optimal performance.
// Parallel execution (default)
await runner.runTests(tests, watcher, { serial: false });Features:
jest-worker to spawn worker processesglobalConfig.maxWorkersworkerIdleMemoryLimitSingle-threaded execution mode that runs tests one by one in the main process.
// Serial execution
await runner.runTests(tests, watcher, { serial: true });
// Sets process.env.JEST_WORKER_ID = '1'Features:
JEST_WORKER_ID = '1'The runner emits typed events throughout test execution for real-time monitoring and integration.
// Available events from TestEvents interface
type TestEvents = {
'test-file-start': [Test];
'test-file-success': [Test, TestResult];
'test-file-failure': [Test, SerializableError];
// Additional events may be forwarded from test frameworks
};Event Flow:
test-file-start - Emitted when a test file begins executiontest-file-success - Emitted when a test file completes successfullytest-file-failure - Emitted when a test file fails or throws an errorThe parallel execution mode uses sophisticated worker management for optimal performance.
Worker Configuration:
globalConfig.maxWorkersworkerIdleMemoryLimitglobalConfig.workerThreadsWorker Communication:
UNSTABLE_onCustomMessageThe runner provides robust error handling and graceful interruption support.
Interruption Handling:
// Watcher-based interruption
const watcher = new TestWatcher({ isWatchMode: true });
watcher.on('change', (state) => {
if (state.interrupted) {
// Tests will be cancelled gracefully
}
});Error Management:
interface Test {
path: string;
context: TestContext;
}
interface TestContext {
config: Config.ProjectConfig;
moduleMap: ModuleMap;
resolver: Resolver;
}
interface TestResult {
numFailingTests: number;
numPassingTests: number;
numPendingTests: number;
numTodoTests: number;
perfStats: TestPerformanceStats;
testFilePath: string;
console: ConsoleBuffer;
leaks: boolean;
// Additional properties for coverage, memory usage, etc.
}
interface SerializableError {
message: string;
stack?: string;
type: string;
code?: string;
}