CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-runner

Jest's test runner responsible for orchestrating test execution, managing worker processes, and coordinating parallel test runs

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

core-execution.mddocs/

Core Test Execution

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.

Capabilities

RunTest Function

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.

Test Execution Process

The runTest function follows a comprehensive execution process with multiple phases.

Execution Phases:

  1. File Analysis: Read test file and parse docblock pragmas
  2. Environment Resolution: Determine test environment (node, jsdom, custom)
  3. Transformer Setup: Configure code transformation pipeline
  4. Environment Creation: Instantiate test environment with console setup
  5. Runtime Initialization: Create Jest runtime with module caching
  6. Setup Files: Execute project setup files and configuration
  7. Test Framework Execution: Run the actual test using configured framework
  8. Result Collection: Gather test results, coverage, and performance data
  9. Cleanup: Tear down environment and release resources

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
});

Test Framework Integration

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:

  • Uses process.env.JEST_JASMINE === '1' for Jasmine2 compatibility
  • Falls back to projectConfig.testRunner (default: Jest Circus)
  • Supports custom test frameworks implementing the TestFramework interface

Console and Logging Management

Sophisticated 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.

Performance and Memory Tracking

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:

  • Optional leak detection with LeakDetector
  • Heap usage tracking when globalConfig.logHeapUsage is enabled
  • Garbage collection before memory measurement
  • Source map cleanup to prevent memory leaks

Coverage Collection

Support 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;
  }
}

Error Handling and Process Management

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:

  • Increases Error.stackTraceLimit to 100 for better debugging
  • Installs source map support for both runtime and test errors
  • Preserves error stack traces before uninstalling source maps

Setup Files Execution

Handles 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();
    }
  }
}

Types

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;
}

docs

core-execution.md

custom-runner.md

index.md

test-runner.md

worker-management.md

tile.json