or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-execution.mdcustom-runner.mdindex.mdtest-runner.mdworker-management.md
tile.json

core-execution.mddocs/

0

# Core Test Execution

1

2

The fundamental `runTest` function that executes individual test files with environment setup, framework integration, and result collection. This is the core engine that handles all aspects of running a single test file.

3

4

## Capabilities

5

6

### RunTest Function

7

8

The main test execution function that handles complete test lifecycle for individual test files.

9

10

```typescript { .api }

11

/**

12

* Execute a single test file with complete environment setup and teardown

13

* @param path - Absolute path to the test file

14

* @param globalConfig - Jest global configuration

15

* @param config - Project-specific configuration

16

* @param resolver - Module resolver for the test

17

* @param context - Test runner context with changed files information

18

* @param sendMessageToJest - Optional callback for sending events to Jest

19

* @returns Promise resolving to complete test results

20

*/

21

export default function runTest(

22

path: string,

23

globalConfig: Config.GlobalConfig,

24

config: Config.ProjectConfig,

25

resolver: Resolver,

26

context: TestRunnerContext,

27

sendMessageToJest?: TestFileEvent

28

): Promise<TestResult>;

29

```

30

31

**Usage Examples:**

32

33

The `runTest` function is internal to the jest-runner package and not directly exported. It is used internally by the `TestRunner` class. For most use cases, you should use the `TestRunner` class instead:

34

35

```typescript

36

import TestRunner from "jest-runner";

37

import { TestWatcher } from "jest-watcher";

38

import type { Test } from "@jest/test-result";

39

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

40

41

// Use TestRunner to execute tests (recommended approach)

42

const runner = new TestRunner(globalConfig, context);

43

const watcher = new TestWatcher({ isWatchMode: false });

44

45

await runner.runTests([test], watcher, { serial: true });

46

```

47

48

Note: The `runTest` function is used internally by `TestRunner` for individual test execution but is not part of the public API.

49

50

### Test Execution Process

51

52

The `runTest` function follows a comprehensive execution process with multiple phases.

53

54

**Execution Phases:**

55

56

1. **File Analysis**: Read test file and parse docblock pragmas

57

2. **Environment Resolution**: Determine test environment (node, jsdom, custom)

58

3. **Transformer Setup**: Configure code transformation pipeline

59

4. **Environment Creation**: Instantiate test environment with console setup

60

5. **Runtime Initialization**: Create Jest runtime with module caching

61

6. **Setup Files**: Execute project setup files and configuration

62

7. **Test Framework Execution**: Run the actual test using configured framework

63

8. **Result Collection**: Gather test results, coverage, and performance data

64

9. **Cleanup**: Tear down environment and release resources

65

66

**Environment Setup:**

67

68

```typescript

69

// Test environment resolution from docblock or config

70

const testEnvironment = customEnvironment || projectConfig.testEnvironment;

71

const TestEnvironment = await transformer.requireAndTranspileModule(testEnvironment);

72

73

// Environment instantiation with configuration

74

const environment = new TestEnvironment({

75

globalConfig,

76

projectConfig: {

77

...projectConfig,

78

testEnvironmentOptions: {

79

...projectConfig.testEnvironmentOptions,

80

...extraTestEnvironmentOptions

81

}

82

}

83

}, {

84

console: testConsole,

85

docblockPragmas,

86

testPath: path

87

});

88

```

89

90

### Test Framework Integration

91

92

The function integrates with configurable test frameworks (Jest Circus, Jasmine, custom frameworks).

93

94

```typescript { .api }

95

/**

96

* Test framework function signature that runTest expects

97

*/

98

type TestFramework = (

99

globalConfig: Config.GlobalConfig,

100

config: Config.ProjectConfig,

101

environment: JestEnvironment,

102

runtime: RuntimeType,

103

testPath: string,

104

sendMessageToJest?: TestFileEvent

105

) => Promise<TestResult>;

106

```

107

108

**Framework Selection:**

109

- Uses `process.env.JEST_JASMINE === '1'` for Jasmine2 compatibility

110

- Falls back to `projectConfig.testRunner` (default: Jest Circus)

111

- Supports custom test frameworks implementing the `TestFramework` interface

112

113

### Console and Logging Management

114

115

Sophisticated console handling for different Jest modes and output capture.

116

117

**Console Modes:**

118

119

```typescript

120

// Silent mode - no output

121

if (globalConfig.silent) {

122

testConsole = new NullConsole(consoleOut, consoleOut, consoleFormatter);

123

}

124

125

// Verbose mode - immediate output

126

else if (globalConfig.verbose) {

127

testConsole = new CustomConsole(consoleOut, consoleOut, consoleFormatter);

128

}

129

130

// Default mode - buffered output

131

else {

132

testConsole = new BufferedConsole();

133

}

134

```

135

136

**Console Freezing:**

137

After test completion, the console is "frozen" to prevent logging after test completion, which helps detect asynchronous cleanup issues.

138

139

### Performance and Memory Tracking

140

141

Comprehensive performance monitoring and memory leak detection.

142

143

**Performance Metrics:**

144

145

```typescript { .api }

146

interface TestPerformanceStats {

147

start: number;

148

end: number;

149

runtime: number;

150

slow: boolean;

151

loadTestEnvironmentStart: number;

152

loadTestEnvironmentEnd: number;

153

setupFilesStart: number;

154

setupFilesEnd: number;

155

}

156

```

157

158

**Memory Management:**

159

- Optional leak detection with `LeakDetector`

160

- Heap usage tracking when `globalConfig.logHeapUsage` is enabled

161

- Garbage collection before memory measurement

162

- Source map cleanup to prevent memory leaks

163

164

### Coverage Collection

165

166

Support for both Babel-based and V8-based code coverage collection.

167

168

**Coverage Types:**

169

170

```typescript

171

// Babel-based coverage (default)

172

const coverage = runtime.getAllCoverageInfoCopy();

173

if (coverage && Object.keys(coverage).length > 0) {

174

result.coverage = coverage;

175

}

176

177

// V8-based coverage (when configured)

178

if (collectV8Coverage) {

179

await runtime.collectV8Coverage();

180

// ... execute test ...

181

await runtime.stopCollectingV8Coverage();

182

183

const v8Coverage = runtime.getAllV8CoverageInfoCopy();

184

if (v8Coverage && v8Coverage.length > 0) {

185

result.v8Coverage = v8Coverage;

186

}

187

}

188

```

189

190

### Error Handling and Process Management

191

192

Robust error handling with proper cleanup and process exit prevention.

193

194

**Process Exit Prevention:**

195

```typescript

196

// Override process.exit to prevent tests from killing the process

197

if (environment.global && environment.global.process && environment.global.process.exit) {

198

const realExit = environment.global.process.exit;

199

200

environment.global.process.exit = function exit(...args: Array<any>) {

201

const error = new ErrorWithStack(

202

`process.exit called with "${args.join(', ')}"`,

203

exit

204

);

205

// Log formatted error and call real exit

206

const formattedError = formatExecError(error, projectConfig, {noStackTrace: false});

207

process.stderr.write(formattedError);

208

return realExit(...args);

209

};

210

}

211

```

212

213

**Stack Trace Enhancement:**

214

- Increases `Error.stackTraceLimit` to 100 for better debugging

215

- Installs source map support for both runtime and test errors

216

- Preserves error stack traces before uninstalling source maps

217

218

### Setup Files Execution

219

220

Handles project-level setup files with support for both CommonJS and ESM.

221

222

```typescript

223

// Execute setup files before test execution

224

for (const path of projectConfig.setupFiles) {

225

const esm = runtime.unstable_shouldLoadAsEsm(path);

226

227

if (esm) {

228

await runtime.unstable_importModule(path);

229

} else {

230

const setupFile = runtime.requireModule(path);

231

if (typeof setupFile === 'function') {

232

await setupFile();

233

}

234

}

235

}

236

```

237

238

## Types

239

240

```typescript { .api }

241

interface TestResult {

242

console: ConsoleBuffer;

243

coverage?: CoverageMap;

244

displayName?: Config.DisplayName;

245

leaks: boolean;

246

memoryUsage?: number;

247

numFailingTests: number;

248

numPassingTests: number;

249

numPendingTests: number;

250

numTodoTests: number;

251

perfStats: TestPerformanceStats;

252

skipped: boolean;

253

testFilePath: string;

254

testResults: Array<AssertionResult>;

255

v8Coverage?: V8CoverageResult[];

256

}

257

258

interface TestRunnerContext {

259

changedFiles?: Set<string>;

260

sourcesRelatedToTestsInChangedFiles?: Set<string>;

261

}

262

263

interface AssertionResult {

264

ancestorTitles: Array<string>;

265

duration?: number;

266

failureDetails: Array<unknown>;

267

failureMessages: Array<string>;

268

fullName: string;

269

invocations?: number;

270

location?: Callsite;

271

numPassingAsserts: number;

272

retryReasons?: Array<string>;

273

status: 'passed' | 'failed' | 'skipped' | 'pending' | 'todo' | 'disabled';

274

title: string;

275

}

276

277

interface ConsoleBuffer extends Array<LogEntry> {}

278

279

interface LogEntry {

280

message: string;

281

origin: string;

282

type: LogType;

283

}

284

285

type LogType = 'assert' | 'count' | 'debug' | 'dir' | 'dirxml' | 'error' | 'group' | 'groupCollapsed' | 'groupEnd' | 'info' | 'log' | 'time' | 'warn';

286

287

type TestFileEvent = (

288

eventName: string,

289

args: Array<any>

290

) => void | Promise<void>;

291

292

interface JestEnvironment {

293

global: typeof globalThis;

294

getVmContext(): vm.Context | null;

295

setup(): Promise<void>;

296

teardown(): Promise<void>;

297

}

298

299

interface Callsite {

300

column: number;

301

line: number;

302

}

303

```