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 fundamental runTest function that executes individual test files with environment setup, framework integration, and result collection. This is the core engine that handles all aspects of running a single test file.
The main test execution function that handles complete test lifecycle for individual test files.
/**
* Execute a single test file with complete environment setup and teardown
* @param path - Absolute path to the test file
* @param globalConfig - Jest global configuration
* @param config - Project-specific configuration
* @param resolver - Module resolver for the test
* @param context - Test runner context with changed files information
* @param sendMessageToJest - Optional callback for sending events to Jest
* @returns Promise resolving to complete test results
*/
export default function runTest(
path: string,
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
resolver: Resolver,
context: TestRunnerContext,
sendMessageToJest?: TestFileEvent
): Promise<TestResult>;Usage Examples:
The runTest function is internal to the jest-runner package and not directly exported. It is used internally by the TestRunner class. For most use cases, you should use the TestRunner class instead:
import TestRunner from "jest-runner";
import { TestWatcher } from "jest-watcher";
import type { Test } from "@jest/test-result";
import type { Config } from "@jest/types";
// Use TestRunner to execute tests (recommended approach)
const runner = new TestRunner(globalConfig, context);
const watcher = new TestWatcher({ isWatchMode: false });
await runner.runTests([test], watcher, { serial: true });Note: The runTest function is used internally by TestRunner for individual test execution but is not part of the public API.
The runTest function follows a comprehensive execution process with multiple phases.
Execution Phases:
Environment Setup:
// Test environment resolution from docblock or config
const testEnvironment = customEnvironment || projectConfig.testEnvironment;
const TestEnvironment = await transformer.requireAndTranspileModule(testEnvironment);
// Environment instantiation with configuration
const environment = new TestEnvironment({
globalConfig,
projectConfig: {
...projectConfig,
testEnvironmentOptions: {
...projectConfig.testEnvironmentOptions,
...extraTestEnvironmentOptions
}
}
}, {
console: testConsole,
docblockPragmas,
testPath: path
});The function integrates with configurable test frameworks (Jest Circus, Jasmine, custom frameworks).
/**
* Test framework function signature that runTest expects
*/
type TestFramework = (
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
environment: JestEnvironment,
runtime: RuntimeType,
testPath: string,
sendMessageToJest?: TestFileEvent
) => Promise<TestResult>;Framework Selection:
process.env.JEST_JASMINE === '1' for Jasmine2 compatibilityprojectConfig.testRunner (default: Jest Circus)TestFramework interfaceSophisticated console handling for different Jest modes and output capture.
Console Modes:
// Silent mode - no output
if (globalConfig.silent) {
testConsole = new NullConsole(consoleOut, consoleOut, consoleFormatter);
}
// Verbose mode - immediate output
else if (globalConfig.verbose) {
testConsole = new CustomConsole(consoleOut, consoleOut, consoleFormatter);
}
// Default mode - buffered output
else {
testConsole = new BufferedConsole();
}Console Freezing: After test completion, the console is "frozen" to prevent logging after test completion, which helps detect asynchronous cleanup issues.
Comprehensive performance monitoring and memory leak detection.
Performance Metrics:
interface TestPerformanceStats {
start: number;
end: number;
runtime: number;
slow: boolean;
loadTestEnvironmentStart: number;
loadTestEnvironmentEnd: number;
setupFilesStart: number;
setupFilesEnd: number;
}Memory Management:
LeakDetectorglobalConfig.logHeapUsage is enabledSupport for both Babel-based and V8-based code coverage collection.
Coverage Types:
// Babel-based coverage (default)
const coverage = runtime.getAllCoverageInfoCopy();
if (coverage && Object.keys(coverage).length > 0) {
result.coverage = coverage;
}
// V8-based coverage (when configured)
if (collectV8Coverage) {
await runtime.collectV8Coverage();
// ... execute test ...
await runtime.stopCollectingV8Coverage();
const v8Coverage = runtime.getAllV8CoverageInfoCopy();
if (v8Coverage && v8Coverage.length > 0) {
result.v8Coverage = v8Coverage;
}
}Robust error handling with proper cleanup and process exit prevention.
Process Exit Prevention:
// Override process.exit to prevent tests from killing the process
if (environment.global && environment.global.process && environment.global.process.exit) {
const realExit = environment.global.process.exit;
environment.global.process.exit = function exit(...args: Array<any>) {
const error = new ErrorWithStack(
`process.exit called with "${args.join(', ')}"`,
exit
);
// Log formatted error and call real exit
const formattedError = formatExecError(error, projectConfig, {noStackTrace: false});
process.stderr.write(formattedError);
return realExit(...args);
};
}Stack Trace Enhancement:
Error.stackTraceLimit to 100 for better debuggingHandles project-level setup files with support for both CommonJS and ESM.
// Execute setup files before test execution
for (const path of projectConfig.setupFiles) {
const esm = runtime.unstable_shouldLoadAsEsm(path);
if (esm) {
await runtime.unstable_importModule(path);
} else {
const setupFile = runtime.requireModule(path);
if (typeof setupFile === 'function') {
await setupFile();
}
}
}interface TestResult {
console: ConsoleBuffer;
coverage?: CoverageMap;
displayName?: Config.DisplayName;
leaks: boolean;
memoryUsage?: number;
numFailingTests: number;
numPassingTests: number;
numPendingTests: number;
numTodoTests: number;
perfStats: TestPerformanceStats;
skipped: boolean;
testFilePath: string;
testResults: Array<AssertionResult>;
v8Coverage?: V8CoverageResult[];
}
interface TestRunnerContext {
changedFiles?: Set<string>;
sourcesRelatedToTestsInChangedFiles?: Set<string>;
}
interface AssertionResult {
ancestorTitles: Array<string>;
duration?: number;
failureDetails: Array<unknown>;
failureMessages: Array<string>;
fullName: string;
invocations?: number;
location?: Callsite;
numPassingAsserts: number;
retryReasons?: Array<string>;
status: 'passed' | 'failed' | 'skipped' | 'pending' | 'todo' | 'disabled';
title: string;
}
interface ConsoleBuffer extends Array<LogEntry> {}
interface LogEntry {
message: string;
origin: string;
type: LogType;
}
type LogType = 'assert' | 'count' | 'debug' | 'dir' | 'dirxml' | 'error' | 'group' | 'groupCollapsed' | 'groupEnd' | 'info' | 'log' | 'time' | 'warn';
type TestFileEvent = (
eventName: string,
args: Array<any>
) => void | Promise<void>;
interface JestEnvironment {
global: typeof globalThis;
getVmContext(): vm.Context | null;
setup(): Promise<void>;
teardown(): Promise<void>;
}
interface Callsite {
column: number;
line: number;
}