Integrating Stryker for Mutation Testing in a TypeScript/Jest Project
This challenge focuses on setting up Stryker, a powerful mutation testing tool, within a TypeScript project using Jest as the testing framework. Mutation testing introduces artificial "bugs" (mutations) into your code and then runs your tests to see if they catch these mutations. Successfully integrating Stryker allows you to identify areas of your codebase with inadequate test coverage and improve the overall robustness of your application.
Problem Description
You are tasked with configuring Stryker to run mutation tests on an existing TypeScript project that utilizes Jest for testing. The project contains a simple utility function and a corresponding Jest test suite. Your goal is to integrate Stryker, configure it appropriately, and run a mutation test to assess the effectiveness of your existing tests. You need to ensure Stryker can correctly parse your TypeScript code, identify mutations, and report the results. The project structure is provided below.
Key Requirements:
- Install Stryker and necessary plugins: Install Stryker and the
@stryker-mutator/typescriptplugin. - Configure Stryker: Create a
stryker.conf.tsfile to configure Stryker's behavior, including the Jest reporter. - Run Mutation Tests: Execute Stryker to perform mutation testing on the specified source files and test files.
- Analyze Results: Stryker should generate a report indicating which mutations were killed (detected by your tests) and which survived (not detected).
Expected Behavior:
- Stryker should successfully parse the TypeScript code.
- Stryker should identify mutations within the utility function.
- The Jest reporter should accurately report the mutation test results.
- The report should clearly indicate the mutation score (percentage of mutations killed).
Edge Cases to Consider:
- Ensure Stryker correctly handles TypeScript syntax and types.
- Consider how Stryker interacts with Jest's mocking and other features.
- Handle potential errors during Stryker's execution gracefully.
Examples
Example 1:
Project Structure:
src/
utils.ts (Contains the utility function)
test/
utils.test.ts (Jest tests for utils.ts)
stryker.conf.ts (Configuration file)
utils.ts:
export function add(a: number, b: number): number {
return a + b;
}
utils.test.ts:
import { add } from '../src/utils';
describe('add', () => {
it('should add two numbers correctly', () => {
expect(add(1, 2)).toBe(3);
});
});
stryker.conf.ts:
module.exports = {
project: {
test: 'test/**/*.test.ts',
source: 'src/**/*.ts',
},
mutator: 'typescript',
reporter: 'html'
};
Output: (After running Stryker) A report (likely HTML) showing that the mutation "replace '+' with '-' in utils.ts" survived because the test only checks for positive numbers. The mutation score would be less than 100%.
Explanation: The test case only verifies the addition of positive numbers. Stryker will introduce a mutation that changes the + to -. Because the test case doesn't cover the scenario where the result is negative, the mutation survives, indicating a gap in test coverage.
Example 2:
Project Structure: (Same as Example 1)
utils.ts:
export function add(a: number, b: number): number {
return a + b;
}
utils.test.ts:
import { add } from '../src/utils';
describe('add', () => {
it('should add two numbers correctly', () => {
expect(add(1, 2)).toBe(3);
});
it('should add two negative numbers correctly', () => {
expect(add(-1, -2)).toBe(-3);
});
});
stryker.conf.ts:
module.exports = {
project: {
test: 'test/**/*.test.ts',
source: 'src/**/*.ts',
},
mutator: 'typescript',
reporter: 'html'
};
Output: (After running Stryker) A report (likely HTML) showing a high mutation score (close to 100%). All mutations are killed.
Explanation: The addition of the second test case, covering negative numbers, ensures that Stryker's mutations involving changes to the addition operation are detected.
Constraints
- Dependencies: You must use Stryker version 7 or higher.
- TypeScript Version: The project uses TypeScript 4.x or higher.
- Jest Version: The project uses Jest 27 or higher.
- Mutation Score: Aim for a mutation score of at least 80% (though achieving 100% is often difficult).
- Report Format: The report should be in HTML format.
Notes
- Start by installing Stryker and the TypeScript plugin.
- The
stryker.conf.tsfile is crucial for configuring Stryker. Pay close attention to theprojectandreporteroptions. - Consider using a CI/CD pipeline to automatically run Stryker mutation tests on every code change.
- Mutation testing can be computationally expensive, especially for large projects. Start with a small subset of code to get familiar with the process.
- The provided example project structure is a simplified starting point. Your actual project may have a more complex structure. Adjust the
sourceandtestpaths instryker.conf.tsaccordingly. - Review Stryker's documentation for detailed information on configuration options and best practices: https://stryker-mutator.io/