CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stryker-mutator--jest-runner

A plugin to use the jest test runner and framework in Stryker, the JavaScript mutation testing framework

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration Management

Configuration loading and validation for different Jest project types including custom projects and Create React App setups. Handles Jest config merging and validation.

Capabilities

Jest Configuration Options

Core configuration interface for customizing Jest runner behavior within Stryker.

/**
 * Jest-specific configuration options for Stryker Jest runner
 */
export interface JestOptions {
  /** Type of Jest project setup */
  projectType: JestProjectType;
  /** Path to Jest configuration file (optional) */
  configFile?: string;
  /** Custom Jest configuration object (optional) */
  config?: { [k: string]: unknown };
  /** Enable Jest's --findRelatedTests flag for optimized test execution */
  enableFindRelatedTests: boolean;
}

/**
 * Supported Jest project types
 */
export type JestProjectType = 'create-react-app' | 'custom';

Usage Examples:

// stryker.conf.js - Custom project configuration
module.exports = {
  testRunner: "jest",
  jest: {
    projectType: "custom",
    configFile: "./jest.config.js",
    enableFindRelatedTests: true,
    config: {
      testEnvironment: "node",
      collectCoverageFrom: ["src/**/*.{js,ts}"],
      coverageReporters: ["text", "lcov"]
    }
  }
};
// stryker.conf.js - Create React App project  
module.exports = {
  testRunner: "jest",
  jest: {
    projectType: "create-react-app",
    enableFindRelatedTests: false
  }
};

Complete Options Interface

Root configuration interface that combines Jest options with Stryker options.

/**
 * Root Jest runner options interface
 */
export interface JestRunnerOptions {
  jest: JestOptions;
  [k: string]: unknown;
}

/**
 * Combined interface extending Stryker core options with Jest options
 */
export interface JestRunnerOptionsWithStrykerOptions extends StrykerOptions, JestRunnerOptions {}

Usage Example:

import { JestRunnerOptionsWithStrykerOptions } from "@stryker-mutator/jest-runner";

// Used internally by Stryker to type check complete configuration
const config: JestRunnerOptionsWithStrykerOptions = {
  // Stryker core options
  mutate: ['src/**/*.js'],
  testRunner: 'jest',
  coverageAnalysis: 'perTest',
  
  // Jest-specific options
  jest: {
    projectType: 'custom',
    enableFindRelatedTests: true,
    config: {
      testMatch: ['**/__tests__/**/*.test.js']
    }
  }
};

Configuration Loaders

Abstract interface and implementations for loading Jest configuration from different sources.

/**
 * Base interface for Jest configuration loaders
 */
export interface JestConfigLoader {
  loadConfig(): Promise<Config.InitialOptions>;
}

/**
 * Configuration loader for custom Jest projects
 * Loads configuration from Jest config files, package.json, or defaults
 */
export class CustomJestConfigLoader implements JestConfigLoader {
  loadConfig(): Promise<Config.InitialOptions>;
}

/**
 * Configuration loader for Create React App projects
 * Uses react-scripts Jest configuration with CRA-specific optimizations
 */
export class ReactScriptsJestConfigLoader implements JestConfigLoader {
  loadConfig(): Promise<Config.InitialOptions>;
}

/**
 * Factory function to create appropriate config loader based on project type
 * @param options - Stryker options containing Jest configuration
 * @param injector - Dependency injector for creating loader instances
 * @param log - Logger for configuration warnings and debug information
 * @returns Configured Jest config loader instance
 */
export function configLoaderFactory(
  options: StrykerOptions,
  injector: Injector<JestPluginContext>,
  log: Logger
): CustomJestConfigLoader | ReactScriptsJestConfigLoader;

Usage Examples:

import { configLoaderFactory, CustomJestConfigLoader } from "@stryker-mutator/jest-runner";

// Typically used internally by Stryker through dependency injection
const loader = configLoaderFactory(options, injector, logger);
const jestConfig = await loader.loadConfig();

// Direct usage for custom scenarios  
const customLoader = new CustomJestConfigLoader(/* dependencies */);
const config = await customLoader.loadConfig();

Jest Override Options

Default configuration overrides applied by Stryker for optimal mutation testing performance.

/**
 * Default Jest configuration overrides for Stryker integration
 * Applied to all Jest configurations to optimize for mutation testing
 */
export const JEST_OVERRIDE_OPTIONS: Readonly<Config.InitialOptions>;

The override options disable Jest features that interfere with mutation testing:

const JEST_OVERRIDE_OPTIONS = {
  // Prevent conflicts with Stryker's result processing
  testResultsProcessor: undefined,
  
  // Disable Jest's built-in coverage collection (Stryker handles this)
  collectCoverage: false,
  
  // Reduce verbose output during mutation testing
  verbose: false,
  
  // Disable desktop notifications during testing
  notify: false,
  
  // Ensure all tests run (bail not supported programmatically)
  bail: false,
  
  // Disable default reporters for cleaner output
  reporters: [],
};

Usage Example:

import { JEST_OVERRIDE_OPTIONS } from "@stryker-mutator/jest-runner";

// These overrides are automatically applied by the Jest runner
// but can be inspected for debugging or custom integrations
console.log('Stryker Jest overrides:', JEST_OVERRIDE_OPTIONS);

// Example of manual config merging (typically done internally)
const finalConfig = {
  ...userJestConfig,
  ...customOptions,
  ...JEST_OVERRIDE_OPTIONS  // Applied last to ensure overrides take effect
};

Types

Configuration Schema Types

// From Jest types
namespace Config {
  interface InitialOptions {
    testEnvironment?: string;
    testRunner?: string;
    setupFiles?: string[];
    setupFilesAfterEnv?: string[];
    testMatch?: string[];
    testPathIgnorePatterns?: string[];
    collectCoverageFrom?: string[];
    coverageDirectory?: string;
    roots?: string[];
    globals?: { [key: string]: any };
    // ... many more Jest configuration options
  }
  
  interface GlobalConfig extends InitialOptions {
    // Resolved global configuration
  }
  
  interface ProjectConfig extends InitialOptions {
    // Resolved project-specific configuration
  }
}

Stryker Integration Types

interface StrykerOptions {
  mutate: string[];
  testRunner: string;
  coverageAnalysis: CoverageAnalysis;
  files: string[];
  // ... other Stryker core options
}

type CoverageAnalysis = 'off' | 'all' | 'perTest';

Dependency Injection Types

interface JestPluginContext extends PluginContext {
  [pluginTokens.jestWrapper]: JestWrapper;
  [pluginTokens.resolve]: RequireResolve;
  [pluginTokens.requireFromCwd]: typeof requireResolve;
  [pluginTokens.processEnv]: typeof process.env;
  [pluginTokens.jestConfigWrapper]: JestConfigWrapper;
}

const pluginTokens = {
  requireFromCwd: 'requireFromCwd',
  resolve: 'resolve',
  resolveFromDirectory: 'resolveFromDirectory',
  configLoader: 'configLoader',
  processEnv: 'processEnv',
  jestTestAdapter: 'jestTestAdapter',
  globalNamespace: 'globalNamespace',
  jestWrapper: 'jestWrapper',
  jestConfigWrapper: 'jestConfigWrapper',
} as const;

Configuration Merging Strategy

The Jest runner applies a layered configuration approach:

1. Base Configuration

Loaded from Jest configuration sources in priority order:

  • Explicit configFile path
  • jest.config.js / jest.config.ts
  • package.json jest property
  • Jest defaults

2. User Configuration

Applied from Stryker jest.config option:

jest: {
  config: {
    // User overrides applied here
    testEnvironment: "jsdom",
    setupFilesAfterEnv: ["./test-setup.js"]
  }
}

3. Stryker Overrides

Internal optimizations for mutation testing:

const JEST_OVERRIDE_OPTIONS = {
  testResultsProcessor: undefined,    // Prevent conflicts
  collectCoverage: false,            // Handled by Stryker
  verbose: false,                    // Reduce noise
  notify: false,                     // Disable notifications  
  bail: false,                       // Run all tests
  reporters: [],                     // Disable default reporters
};

4. Runtime Modifications

Applied during test execution:

  • Coverage analysis environment setup
  • Hit limit environment configuration
  • Test file path adjustments
  • Global namespace injection

Project Type Behaviors

Custom Projects (projectType: "custom")

  • Config Loading: Uses standard Jest configuration resolution
  • Config File Support: Respects configFile option for custom paths
  • Flexibility: Full access to Jest configuration options
  • Use Case: Most Node.js and custom TypeScript projects
jest: {
  projectType: "custom",
  configFile: "./config/jest.config.js",
  config: {
    preset: "ts-jest",
    testEnvironment: "node"
  }
}

Create React App Projects (projectType: "create-react-app")

  • Config Loading: Uses react-scripts Jest configuration
  • Config File Ignored: configFile option ignored with warning
  • CRA Optimizations: Leverages CRA's built-in Jest setup
  • Use Case: Projects created with create-react-app
jest: {
  projectType: "create-react-app",
  enableFindRelatedTests: false  // Often disabled for CRA
}

Performance Optimizations

Related Tests (enableFindRelatedTests)

When enabled, Jest runs only tests related to mutated files:

  • Faster Execution: Reduces test execution time
  • Smart Filtering: Uses Jest's dependency analysis
  • Mutation Testing: Ideal for large codebases
  • Trade-off: May miss some integration test scenarios

Configuration Caching

  • Loaded Once: Configuration loaded during initialization
  • Merged Strategically: Applied in optimal order
  • Validated Early: Schema validation prevents runtime errors
  • Dependency Resolved: External dependencies resolved upfront

Environment Optimization

  • Minimal Setup: Only necessary Jest features enabled
  • Disabled Features: Coverage, reporters, and notifications turned off
  • Environment Variables: Optimized for test execution speed
  • Memory Management: Efficient cleanup after test runs

Install with Tessl CLI

npx tessl i tessl/npm-stryker-mutator--jest-runner

docs

configuration.md

environment-integration.md

index.md

plugin-integration.md

test-runner.md

utilities.md

tile.json