or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-integration.mdindex.mdtest-discovery.mdtest-scheduling.md
tile.json

cli-integration.mddocs/

0

# CLI Integration

1

2

Programmatic interface to Jest's command-line functionality, supporting all CLI options and returning structured results. The runCLI function provides a complete CLI-compatible interface perfect for build tools, CI systems, and custom test runners.

3

4

## Capabilities

5

6

### CLI Runner Function

7

8

Main function providing complete Jest CLI functionality programmatically.

9

10

```typescript { .api }

11

/**

12

* Runs Jest with command-line arguments and project paths

13

* @param argv - Jest CLI arguments and configuration options

14

* @param projects - Array of project paths to run tests for

15

* @returns Promise resolving to test results and global configuration

16

*/

17

export async function runCLI(

18

argv: Config.Argv,

19

projects: Array<string>

20

): Promise<{

21

results: AggregatedResult;

22

globalConfig: Config.GlobalConfig;

23

}>;

24

```

25

26

**Basic Usage Example:**

27

28

```typescript

29

import { runCLI } from "@jest/core";

30

import { Config } from "@jest/types";

31

32

// Define CLI arguments similar to command line usage

33

const argv: Config.Argv = {

34

// Test discovery

35

testMatch: ["**/__tests__/**/*.test.js"],

36

testPathIgnorePatterns: ["/node_modules/", "/build/"],

37

38

// Output options

39

verbose: true,

40

coverage: true,

41

coverageDirectory: "./coverage",

42

43

// Execution options

44

maxWorkers: 4,

45

runInBand: false,

46

47

// Other options

48

bail: false,

49

forceExit: true,

50

};

51

52

const projects = ["./src", "./packages/utils"];

53

54

try {

55

const { results, globalConfig } = await runCLI(argv, projects);

56

57

console.log(`Tests run: ${results.numTotalTests}`);

58

console.log(`Tests passed: ${results.numPassedTests}`);

59

console.log(`Tests failed: ${results.numFailedTests}`);

60

console.log(`Success: ${results.success}`);

61

62

// Exit with appropriate code

63

process.exit(results.success ? 0 : 1);

64

} catch (error) {

65

console.error("Jest execution failed:", error);

66

process.exit(1);

67

}

68

```

69

70

**Important Note**: When `watch: true` or `watchAll: true` is set in argv, the runCLI function will return a Promise that never resolves, as Jest enters watch mode and monitors for file changes. The function will only complete when the watch process is interrupted (Ctrl+C) or terminated externally.

71

72

## Configuration Options

73

74

### Test Discovery Options

75

76

Configure how Jest finds and filters test files.

77

78

```typescript

79

const discoveryConfig: Partial<Config.Argv> = {

80

// Pattern matching

81

testMatch: ["**/__tests__/**/*.test.{js,ts}"],

82

testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",

83

testPathIgnorePatterns: ["/node_modules/", "/dist/"],

84

85

// Root directories

86

rootDir: "./src",

87

roots: ["<rootDir>/src", "<rootDir>/tests"],

88

89

// File extensions

90

moduleFileExtensions: ["js", "ts", "json"],

91

92

// Project selection

93

selectProjects: ["frontend", "backend"],

94

ignoreProjects: ["legacy"],

95

};

96

```

97

98

### Execution Control Options

99

100

Control how tests are executed and scheduled.

101

102

```typescript

103

const executionConfig: Partial<Config.Argv> = {

104

// Parallelization

105

maxWorkers: 4,

106

runInBand: false, // Set to true to disable parallel execution

107

108

// Bail options

109

bail: 1, // Stop after first failure

110

111

// Watch mode

112

watch: false,

113

watchAll: false,

114

115

// Timeout

116

testTimeout: 5000,

117

118

// Cache

119

cache: true,

120

clearCache: false,

121

};

122

```

123

124

### Output and Reporting Options

125

126

Configure test output and reporting formats.

127

128

```typescript

129

const outputConfig: Partial<Config.Argv> = {

130

// Verbosity

131

verbose: true,

132

silent: false,

133

134

// Output formats

135

json: false, // Output results as JSON

136

outputFile: "./test-results.json",

137

138

// Coverage

139

coverage: true,

140

coverageDirectory: "./coverage",

141

collectCoverageFrom: [

142

"src/**/*.{js,ts}",

143

"!src/**/*.test.{js,ts}",

144

"!src/**/*.d.ts",

145

],

146

coverageThreshold: {

147

global: {

148

branches: 80,

149

functions: 80,

150

lines: 80,

151

statements: 80,

152

},

153

},

154

155

// Reporters

156

reporters: [

157

"default",

158

["jest-junit", { outputDirectory: "./test-results" }],

159

],

160

161

// Error output

162

useStderr: false,

163

};

164

```

165

166

## Advanced Usage Patterns

167

168

### CI/CD Integration

169

170

```typescript

171

import { runCLI } from "@jest/core";

172

173

async function runTestsForCI() {

174

const isCI = process.env.CI === "true";

175

176

const argv: Config.Argv = {

177

// Optimize for CI

178

maxWorkers: isCI ? 2 : 4,

179

cache: !isCI, // Disable cache in CI

180

coverage: true,

181

coverageReporters: ["text", "lcov", "json"],

182

183

// CI-specific options

184

forceExit: true,

185

detectOpenHandles: true,

186

verbose: false,

187

silent: false,

188

189

// Output for CI tools

190

json: true,

191

outputFile: "./test-results.json",

192

193

// Reporters for CI

194

reporters: [

195

"default",

196

["jest-junit", {

197

outputDirectory: "./test-results",

198

outputName: "junit.xml",

199

}],

200

],

201

};

202

203

const { results } = await runCLI(argv, [process.cwd()]);

204

205

// Generate additional CI artifacts

206

if (isCI) {

207

await generateCoverageReport(results);

208

await uploadTestResults(results);

209

}

210

211

return results;

212

}

213

```

214

215

### Watch Mode Integration

216

217

```typescript

218

async function runWithCustomWatch() {

219

const argv: Config.Argv = {

220

watch: true,

221

watchman: true,

222

watchPathIgnorePatterns: ["/node_modules/", "/build/"],

223

224

// Watch mode specific options

225

onlyChanged: true,

226

changedFilesWithAncestor: true,

227

228

// Minimal output for watch mode

229

verbose: false,

230

coverage: false,

231

};

232

233

// This will run indefinitely in watch mode

234

const { results } = await runCLI(argv, [process.cwd()]);

235

236

// This code won't be reached in watch mode

237

return results;

238

}

239

```

240

241

### Multi-Project Configuration

242

243

```typescript

244

async function runMultiProjectTests() {

245

const argv: Config.Argv = {

246

// Multi-project configuration

247

projects: [

248

{

249

displayName: "frontend",

250

testMatch: ["<rootDir>/src/frontend/**/*.test.js"],

251

testEnvironment: "jsdom",

252

},

253

{

254

displayName: "backend",

255

testMatch: ["<rootDir>/src/backend/**/*.test.js"],

256

testEnvironment: "node",

257

},

258

{

259

displayName: "integration",

260

testMatch: ["<rootDir>/tests/integration/**/*.test.js"],

261

testEnvironment: "node",

262

testTimeout: 30000,

263

},

264

],

265

266

// Run specific projects

267

selectProjects: ["frontend", "backend"],

268

269

// Coverage across projects

270

coverage: true,

271

collectCoverageFrom: [

272

"src/**/*.js",

273

"!src/**/*.test.js",

274

],

275

};

276

277

const { results } = await runCLI(argv, []);

278

279

// Results will contain data from all selected projects

280

console.log("Project results:");

281

results.testResults.forEach(result => {

282

console.log(`${result.displayName}: ${result.numPassingTests} passed`);

283

});

284

285

return results;

286

}

287

```

288

289

### Custom Configuration Loading

290

291

```typescript

292

import * as path from "path";

293

import { readConfigs } from "jest-config";

294

295

async function runWithCustomConfig() {

296

// Load configuration from custom locations

297

const customArgv: Config.Argv = {

298

config: path.resolve("./custom-jest.config.js"),

299

rootDir: process.cwd(),

300

};

301

302

// Validate configuration before running

303

try {

304

const { globalConfig, configs } = await readConfigs(customArgv, [process.cwd()]);

305

306

console.log(`Loaded configuration for ${configs.length} projects`);

307

console.log(`Test timeout: ${globalConfig.testTimeout}ms`);

308

309

const { results } = await runCLI(customArgv, [process.cwd()]);

310

311

return { results, globalConfig };

312

} catch (configError) {

313

console.error("Configuration error:", configError);

314

throw configError;

315

}

316

}

317

```

318

319

## Types

320

321

```typescript { .api }

322

interface Config.Argv {

323

/** Test discovery patterns */

324

testMatch?: Array<string>;

325

testRegex?: Array<string>;

326

testPathIgnorePatterns?: Array<string>;

327

328

/** Execution options */

329

maxWorkers?: number;

330

runInBand?: boolean;

331

bail?: number | boolean;

332

333

/** Watch mode */

334

watch?: boolean;

335

watchAll?: boolean;

336

onlyChanged?: boolean;

337

338

/** Output options */

339

verbose?: boolean;

340

silent?: boolean;

341

json?: boolean;

342

outputFile?: string;

343

344

/** Coverage options */

345

coverage?: boolean;

346

coverageDirectory?: string;

347

collectCoverageFrom?: Array<string>;

348

coverageThreshold?: CoverageThreshold;

349

350

/** Project selection */

351

selectProjects?: Array<string>;

352

ignoreProjects?: Array<string>;

353

354

/** Configuration */

355

config?: string;

356

rootDir?: string;

357

roots?: Array<string>;

358

359

/** Cache options */

360

cache?: boolean;

361

clearCache?: boolean;

362

363

/** Process options */

364

forceExit?: boolean;

365

detectOpenHandles?: boolean;

366

367

/** Reporters */

368

reporters?: Array<string | [string, Record<string, any>]>;

369

370

/** Environment */

371

testEnvironment?: string;

372

testTimeout?: number;

373

}

374

375

interface CoverageThreshold {

376

global?: {

377

branches?: number;

378

functions?: number;

379

lines?: number;

380

statements?: number;

381

};

382

[key: string]: {

383

branches?: number;

384

functions?: number;

385

lines?: number;

386

statements?: number;

387

} | undefined;

388

}

389

```