A plugin to use the jest test runner and framework in Stryker, the JavaScript mutation testing framework
—
Jest environment enhancement utilities that provide Stryker-specific functionality including instrumenter context sharing and test event handling for coverage analysis.
Enhances Jest environment classes with Stryker integration for mutation testing and coverage analysis.
/**
* Mixin function that enhances a Jest environment class with Stryker functionality
* Adds instrumenter context sharing and test event handling for coverage analysis
* @param JestEnvironmentClass - Jest environment class to enhance
* @returns Enhanced Jest environment class with Stryker integration
*/
export function mixinJestEnvironment<T extends typeof JestEnvironment>(
JestEnvironmentClass: T & { [STRYKER_JEST_ENV]?: true }
): T;Usage Examples:
import { mixinJestEnvironment } from "@stryker-mutator/jest-runner";
import NodeEnvironment from "jest-environment-node";
import JSDOMEnvironment from "jest-environment-jsdom";
// Enhance Node.js environment
const StrykerNodeEnvironment = mixinJestEnvironment(NodeEnvironment);
// Enhance JSDOM environment
const StrykerJSDOMEnvironment = mixinJestEnvironment(JSDOMEnvironment);
// Use in Jest configuration
module.exports = {
testEnvironment: StrykerNodeEnvironment,
// or
testEnvironment: "./custom-stryker-environment.js"
};// custom-stryker-environment.js
const { mixinJestEnvironment } = require("@stryker-mutator/jest-runner");
const NodeEnvironment = require("jest-environment-node").default;
module.exports = mixinJestEnvironment(NodeEnvironment);The package provides pre-built Jest environments with Stryker integration for common use cases.
// Available as CommonJS exports through package.json exports map
// Node.js environment with Stryker integration
"@stryker-mutator/jest-runner/jest-env/node"
// JSDOM environment with Stryker integration
"@stryker-mutator/jest-runner/jest-env/jsdom"
// JSDOM v16 environment with Stryker integration
"@stryker-mutator/jest-runner/jest-env/jsdom-sixteen"Usage Examples:
// Jest configuration using pre-built environments
module.exports = {
// Use Node.js environment
testEnvironment: "@stryker-mutator/jest-runner/jest-env/node",
// Use JSDOM environment
testEnvironment: "@stryker-mutator/jest-runner/jest-env/jsdom",
// Use JSDOM v16 environment
testEnvironment: "@stryker-mutator/jest-runner/jest-env/jsdom-sixteen"
};// Import for programmatic use
const StrykerNodeEnv = require("@stryker-mutator/jest-runner/jest-env/node");
const StrykerJSDOMEnv = require("@stryker-mutator/jest-runner/jest-env/jsdom");import type {
JestEnvironment,
EnvironmentContext,
JestEnvironmentConfig,
} from '@jest/environment';
import type { Circus } from '@jest/types';
interface StrykerJestEnvironment extends JestEnvironment {
readonly [STRYKER_JEST_ENV]: true;
handleTestEvent: Circus.EventHandler;
}
interface EnvironmentContext {
testPath: string;
docblockPragmas: Record<string, string | string[]>;
console: Console;
}
interface JestEnvironmentConfig {
projectConfig: Config.ProjectConfig;
globalConfig: Config.GlobalConfig;
}namespace Circus {
interface Event {
name: string;
test?: TestEntry;
}
interface TestEntry {
name: string;
parent: DescribeBlock;
}
interface DescribeBlock {
name: string;
parent?: DescribeBlock;
}
interface State {
currentDescribeBlock: DescribeBlock;
currentlyRunningTest?: TestEntry;
}
type EventHandler = (event: Event, state: State) => Promise<void> | void;
}interface InstrumenterContext {
currentTestId?: string;
hitCount?: number;
hitLimit?: number;
activeMutant?: Mutant;
mutantCoverage?: MutantCoverage;
}The mixin creates a shared context between the test environment and Stryker's instrumenter:
global.__stryker__ or custom namespaceThe enhanced environment intercepts Jest test events for coverage analysis:
Per-test coverage analysis requires the environment mixin to:
The mixin is designed to work with any Jest environment:
The environment automatically registers test files with Stryker:
// Tracks which test files have Stryker environment integration
state.testFilesWithStrykerEnvironment.add(context.testPath);This information is used for:
The environment respects custom global namespaces:
// Uses configured namespace or defaults to '__stryker__'
const namespace = this.global.__strykerGlobalNamespace__ ?? '__stryker__';
this.#strykerContext = this.global[namespace] = state.instrumenterContext;This allows for:
Install with Tessl CLI
npx tessl i tessl/npm-stryker-mutator--jest-runner