Mutation Testing Metrics Utilities
The `mutation-testing-metrics` package provides a set of utility functions designed to calculate and aggregate mutation testing metrics from mutation test reports. Currently at version 3.7.3, it is an actively maintained component within the Stryker Mutator ecosystem, with a release cadence that appears to be every few months, addressing bug fixes and minor feature enhancements. Its key differentiators include the ability to programmatically process `MutationTestResult` objects, perform detailed metric calculations, and aggregate multiple module-level reports into a single, consolidated view. This enables developers and CI/CD pipelines to deeply analyze the effectiveness of their test suites, going beyond simple code coverage by evaluating how well tests detect intentionally introduced faults (mutants). It is built with TypeScript, providing strong type guarantees for its API.
Common errors
-
Cannot find module 'mutation-testing-metrics' or its corresponding type declarations.
cause The package is not installed, or the import path is incorrect, or TypeScript cannot find the type definitions.fixEnsure the package is installed: `npm install mutation-testing-metrics` or `yarn add mutation-testing-metrics`. Verify the import path is exactly `mutation-testing-metrics`. -
TypeError: calculateMutationTestMetrics is not a function
cause This typically occurs in a CommonJS environment when trying to access a named export without destructuring it from the `require()` call.fixFor CommonJS, use destructuring: `const { calculateMutationTestMetrics } = require('mutation-testing-metrics');` -
Argument of type '{ ... }' is not assignable to parameter of type 'MutationTestResult'.cause The input object provided to functions like `calculateMutationTestMetrics` does not match the expected structure defined by `mutation-testing-report-schema`.fixReview the `MutationTestResult` schema and ensure your input object conforms to it, including all required properties like `schemaVersion`, `thresholds`, and `files` with their correct internal structures.
Warnings
- gotcha Older versions of `mutation-testing-metrics` might encounter compatibility issues with Node.js 20+. A fix for Node 20 compatibility was released in version 3.7.1, so it's recommended to upgrade if using newer Node.js runtimes.
- gotcha The package relies heavily on the `mutation-testing-report-schema` for its input data structure. Any deviation from this schema will lead to incorrect metric calculations or runtime errors.
- gotcha This package is part of the larger `stryker-mutator` monorepo. While it aims for semantic versioning, its major/minor versions are often synchronized with `mutation-testing-elements` and not strictly with the underlying schema, which can sometimes lead to unexpected versioning behavior if only specific sub-packages are updated.
Install
-
npm install mutation-testing-metrics -
yarn add mutation-testing-metrics -
pnpm add mutation-testing-metrics
Imports
- calculateMutationTestMetrics
const calculateMutationTestMetrics = require('mutation-testing-metrics').calculateMutationTestMetrics;import { calculateMutationTestMetrics } from 'mutation-testing-metrics'; - MetricsResult
import type { MetricsResult } from 'mutation-testing-metrics'; - aggregateResultsByModule
const aggregateResultsByModule = require('mutation-testing-metrics'); // or const { default: aggregateResultsByModule } = require('mutation-testing-metrics');import { aggregateResultsByModule } from 'mutation-testing-metrics';
Quickstart
import { MetricsResult, calculateMutationTestMetrics } from 'mutation-testing-metrics';
import type { MutationTestResult } from 'mutation-testing-report-schema';
// In a real scenario, mutationTestReport would be loaded from a file or generated
const mutationTestReport: MutationTestResult = {
$schema: 'https://raw.githubusercontent.com/stryker-mutator/mutation-testing-elements/master/packages/report-schema/src/mutation-testing-report-schema.json',
schemaVersion: '1.4',
thresholds: {
high: 80,
low: 60
},
files: {
'src/calculator.js': {
language: 'javascript',
mutants: [
{
id: '1',
mutatorName: 'BinaryExpression',
replacement: 'a - b',
location: { start: { line: 1, column: 15 }, end: { line: 1, column: 20 } },
status: 'Survived'
},
{
id: '2',
mutatorName: 'BinaryExpression',
replacement: 'a / b',
location: { start: { line: 1, column: 15 }, end: { line: 1, column: 20 } },
status: 'Killed'
}
],
source: 'const add = (a, b) => a + b;'
},
'src/subtract.js': {
language: 'javascript',
mutants: [
{
id: '3',
mutatorName: 'BinaryExpression',
replacement: 'a + b',
location: { start: { line: 1, column: 18 }, end: { line: 1, column: 23 } },
status: 'NoCoverage'
}
],
source: 'const subtract = (a, b) => a - b;'
}
}
};
const result: MetricsResult = calculateMutationTestMetrics(mutationTestReport);
console.log('--- Mutation Test Metrics ---');
console.log('Total mutants:', result.metrics.totalMutants);
console.log('Killed mutants:', result.metrics.killed);
console.log('Survived mutants:', result.metrics.survived);
console.log('No Coverage mutants:', result.metrics.noCoverage);
console.log('Mutation score:', result.metrics.mutationScore.toFixed(2) + '%');