or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdenvironment-integration.mdindex.mdplugin-integration.mdtest-runner.mdutilities.md

index.mddocs/

0

# StrykerJS Jest Runner

1

2

StrykerJS Jest Runner is a plugin that enables the use of Jest as a test runner and framework within Stryker, the JavaScript mutation testing framework. It provides seamless integration between Jest and Stryker, supporting advanced features like per-test coverage analysis, multiple Jest environments, and optimized test execution for mutation testing workflows.

3

4

## Package Information

5

6

- **Package Name**: @stryker-mutator/jest-runner

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @stryker-mutator/jest-runner`

10

- **Peer Dependency**: `@stryker-mutator/core ~9.1.0`

11

12

## Core Imports

13

14

```typescript

15

import { strykerPlugins, strykerValidationSchema, mixinJestEnvironment } from "@stryker-mutator/jest-runner";

16

```

17

18

For Jest environment integration:

19

20

```javascript

21

// These are pre-enhanced Jest environments (CommonJS exports)

22

// Node.js environment with Stryker integration

23

const JestEnvironmentNode = require("@stryker-mutator/jest-runner/jest-env/node");

24

25

// JSDOM environment with Stryker integration

26

const JestEnvironmentJsdom = require("@stryker-mutator/jest-runner/jest-env/jsdom");

27

28

// JSDOM v16 environment with Stryker integration

29

const JestEnvironmentJsdomSixteen = require("@stryker-mutator/jest-runner/jest-env/jsdom-sixteen");

30

```

31

32

## Basic Usage

33

34

### Stryker Configuration

35

36

```javascript

37

// stryker.conf.js

38

module.exports = {

39

testRunner: "jest",

40

coverageAnalysis: "perTest", // or "all" or "off"

41

jest: {

42

projectType: "custom", // or "create-react-app"

43

enableFindRelatedTests: true,

44

config: {

45

// Custom Jest configuration

46

testEnvironment: "node"

47

}

48

}

49

};

50

```

51

52

### Jest Environment Integration

53

54

```typescript

55

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

56

import { TestEnvironment } from "@jest/environment";

57

58

// Enhance Jest environment with Stryker integration

59

const StrykerJestEnvironment = mixinJestEnvironment(TestEnvironment);

60

```

61

62

## Architecture

63

64

The Jest Runner is built around several key components:

65

66

- **Plugin System**: Integrates with Stryker's plugin architecture using factory pattern

67

- **Test Adapter Pattern**: Abstracts Jest version differences through adapters

68

- **Configuration Management**: Handles Jest config loading for different project types

69

- **Environment Enhancement**: Provides Jest environment mixins for mutation testing

70

- **Coverage Analysis**: Implements per-test and global coverage tracking

71

- **Hit Limiting**: Prevents infinite loops during mutation testing

72

73

## Capabilities

74

75

### Stryker Plugin Integration

76

77

Core plugin registration and validation schema for Stryker integration. Provides the main entry point for using Jest as a test runner in Stryker mutation testing.

78

79

```typescript { .api }

80

export const strykerPlugins: Array<PluginDeclaration>;

81

82

export const strykerValidationSchema: JestRunnerOptionsSchema;

83

```

84

85

[Plugin Integration](./plugin-integration.md)

86

87

### Jest Test Runner

88

89

Main test runner implementation that executes Jest tests within Stryker's mutation testing workflow. Handles dry runs for coverage analysis and mutant runs for testing specific mutations.

90

91

```typescript { .api }

92

export class JestTestRunner implements TestRunner {

93

init(): Promise<void>;

94

capabilities(): TestRunnerCapabilities;

95

dryRun(options: Pick<DryRunOptions, 'coverageAnalysis' | 'files'>): Promise<DryRunResult>;

96

mutantRun(options: MutantRunOptions): Promise<MutantRunResult>;

97

}

98

99

export function createJestTestRunnerFactory(

100

namespace?: typeof INSTRUMENTER_CONSTANTS.NAMESPACE | '__stryker2__'

101

): {

102

(injector: Injector<PluginContext>): JestTestRunner;

103

inject: ['$injector'];

104

};

105

106

export const jestTestRunnerFactory: ReturnType<typeof createJestTestRunnerFactory>;

107

```

108

109

[Test Runner](./test-runner.md)

110

111

### Jest Environment Integration

112

113

Jest environment enhancement utilities that provide Stryker-specific functionality including instrumenter context sharing and test event handling for coverage analysis.

114

115

```typescript { .api }

116

export function mixinJestEnvironment<T extends typeof JestEnvironment>(

117

JestEnvironmentClass: T & { [STRYKER_JEST_ENV]?: true }

118

): T;

119

```

120

121

[Environment Integration](./environment-integration.md)

122

123

### Configuration Management

124

125

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

126

127

```typescript { .api }

128

export interface JestOptions {

129

projectType: JestProjectType;

130

configFile?: string;

131

config?: { [k: string]: unknown };

132

enableFindRelatedTests: boolean;

133

}

134

135

export type JestProjectType = 'create-react-app' | 'custom';

136

137

export interface JestRunnerOptions {

138

jest: JestOptions;

139

[k: string]: unknown;

140

}

141

142

export interface JestRunnerOptionsWithStrykerOptions extends StrykerOptions, JestRunnerOptions {}

143

```

144

145

[Configuration Management](./configuration.md)

146

147

### Utility Functions and Classes

148

149

Core utility functions and wrapper classes for Jest integration, version handling, and coverage validation.

150

151

```typescript { .api }

152

export class JestWrapper {

153

getVersion(): string;

154

}

155

156

export class JestConfigWrapper {

157

// Configuration loading and manipulation utilities

158

}

159

160

export function verifyAllTestFilesHaveCoverage(

161

jestResult: AggregatedResult,

162

testFilesWithStrykerEnvironment: Set<string>

163

): string | undefined;

164

165

export function withCoverageAnalysis(

166

jestConfig: Config.InitialOptions,

167

coverageAnalysis: CoverageAnalysis,

168

jestWrapper: JestWrapper

169

): Config.InitialOptions;

170

171

export function withHitLimit(

172

jestConfig: Config.InitialOptions,

173

hitLimit: number | undefined,

174

jestWrapper: JestWrapper

175

): Config.InitialOptions;

176

177

export const JEST_OVERRIDE_OPTIONS: Readonly<Config.InitialOptions>;

178

179

export const pluginTokens: {

180

readonly requireFromCwd: 'requireFromCwd';

181

readonly resolve: 'resolve';

182

readonly resolveFromDirectory: 'resolveFromDirectory';

183

readonly configLoader: 'configLoader';

184

readonly processEnv: 'processEnv';

185

readonly jestTestAdapter: 'jestTestAdapter';

186

readonly globalNamespace: 'globalNamespace';

187

readonly jestWrapper: 'jestWrapper';

188

readonly jestConfigWrapper: 'jestConfigWrapper';

189

};

190

```

191

192

[Utilities](./utilities.md)

193

194

## Types

195

196

### Core Plugin Types

197

198

```typescript { .api }

199

interface PluginDeclaration {

200

kind: PluginKind;

201

name: string;

202

factory: Function;

203

}

204

205

interface TestRunnerCapabilities {

206

reloadEnvironment: boolean;

207

}

208

```

209

210

### Test Execution Types

211

212

```typescript { .api }

213

interface DryRunOptions {

214

coverageAnalysis: CoverageAnalysis;

215

files: string[];

216

}

217

218

interface MutantRunOptions {

219

activeMutant: Mutant;

220

sandboxFileName: string;

221

testFilter?: string[];

222

disableBail: boolean;

223

hitLimit?: number;

224

}

225

226

interface DryRunResult {

227

status: DryRunStatus;

228

tests?: TestResult[];

229

errorMessage?: string;

230

mutantCoverage?: MutantCoverage;

231

}

232

233

interface MutantRunResult {

234

status: MutantRunStatus;

235

tests?: TestResult[];

236

errorMessage?: string;

237

killedBy?: string[];

238

survivalReason?: string;

239

}

240

```

241

242

### Jest Integration Types

243

244

```typescript { .api }

245

interface RunSettings {

246

jestConfig: Config.InitialOptions;

247

testNamePattern?: string;

248

fileNamesUnderTest?: string[];

249

testLocationInResults?: boolean;

250

}

251

252

interface JestRunResult {

253

results: AggregatedResult;

254

globalConfig: Config.GlobalConfig;

255

}

256

257

interface JestTestAdapter {

258

run(settings: RunSettings): Promise<JestRunResult>;

259

}

260

```

261

262

### Jest and Stryker Core Types

263

264

```typescript { .api }

265

// Jest configuration types (from @jest/types)

266

namespace Config {

267

interface InitialOptions {

268

[key: string]: unknown;

269

testEnvironment?: string;

270

collectCoverageFrom?: string[];

271

coverageReporters?: string[];

272

setupFilesAfterEnv?: string[];

273

transform?: { [key: string]: string };

274

testMatch?: string[];

275

testPathIgnorePatterns?: string[];

276

moduleNameMapping?: { [key: string]: string };

277

}

278

279

interface GlobalConfig extends InitialOptions {

280

projects: ProjectConfig[];

281

watch: boolean;

282

watchman: boolean;

283

}

284

285

interface ProjectConfig extends InitialOptions {

286

displayName?: string;

287

rootDir: string;

288

testMatch: string[];

289

}

290

}

291

292

// Jest test result types (from @jest/test-result)

293

interface AggregatedResult {

294

numFailedTests: number;

295

numPassedTests: number;

296

numPendingTests: number;

297

numTotalTests: number;

298

success: boolean;

299

testResults: TestResult[];

300

}

301

302

// Stryker core types

303

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

304

305

interface Mutant {

306

id: string;

307

fileName: string;

308

mutatorName: string;

309

replacement: string;

310

range: [number, number];

311

}

312

313

enum DryRunStatus {

314

Complete = 'Complete',

315

Error = 'Error',

316

Timeout = 'Timeout'

317

}

318

319

enum MutantRunStatus {

320

Killed = 'Killed',

321

Survived = 'Survived',

322

Timeout = 'Timeout',

323

Error = 'Error'

324

}

325

326

interface TestResult {

327

id: string;

328

name: string;

329

status: TestStatus;

330

timeSpentMs?: number;

331

failureMessage?: string;

332

}

333

334

enum TestStatus {

335

Success = 'Success',

336

Failed = 'Failed',

337

Skipped = 'Skipped'

338

}

339

340

// Stryker constants

341

const INSTRUMENTER_CONSTANTS = {

342

NAMESPACE: '__stryker__'

343

} as const;

344

```