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

test-runner.mddocs/

0

# Test Runner Implementation

1

2

The main `TestRunner` class providing both serial and parallel test execution with event-driven progress reporting, worker process coordination, and real-time test status events.

3

4

## Capabilities

5

6

### TestRunner Class

7

8

The default export implementing `EmittingTestRunner` for comprehensive test execution management.

9

10

```typescript { .api }

11

/**

12

* Main test runner class implementing event-driven test execution

13

* Supports both serial and parallel execution modes with worker management

14

*/

15

export default class TestRunner extends EmittingTestRunner {

16

constructor(globalConfig: Config.GlobalConfig, context: TestRunnerContext);

17

18

/**

19

* Execute a collection of tests with the specified options

20

* @param tests - Array of test objects containing path and context

21

* @param watcher - Test watcher for interrupt handling

22

* @param options - Execution options including serial mode flag

23

* @returns Promise that resolves when all tests complete

24

*/

25

runTests(

26

tests: Array<Test>,

27

watcher: TestWatcher,

28

options: TestRunnerOptions

29

): Promise<void>;

30

31

/**

32

* Register event listener for test execution events

33

* @param eventName - Name of the event to listen for

34

* @param listener - Function to call when event is emitted

35

* @returns Unsubscribe function to remove the listener

36

*/

37

on<Name extends keyof TestEvents>(

38

eventName: Name,

39

listener: (eventData: TestEvents[Name]) => void | Promise<void>

40

): UnsubscribeFn;

41

}

42

```

43

44

**Usage Examples:**

45

46

```typescript

47

import TestRunner from "jest-runner";

48

import { TestWatcher } from "jest-watcher";

49

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

50

51

// Create runner with configuration

52

const runner = new TestRunner(globalConfig, {

53

changedFiles: new Set(["/changed/file.js"]),

54

sourcesRelatedToTestsInChangedFiles: new Set(["/source/file.js"])

55

});

56

57

// Set up event listeners

58

runner.on('test-file-start', ([test]) => {

59

console.log(`Starting: ${test.path}`);

60

});

61

62

runner.on('test-file-success', ([test, result]) => {

63

console.log(`✓ ${test.path} - ${result.numPassingTests} tests passed`);

64

});

65

66

runner.on('test-file-failure', ([test, error]) => {

67

console.error(`✗ ${test.path} failed:`, error.message);

68

});

69

70

// Execute tests in parallel

71

await runner.runTests(tests, watcher, { serial: false });

72

73

// Execute tests serially (useful for debugging)

74

await runner.runTests(tests, watcher, { serial: true });

75

```

76

77

### Test Execution Modes

78

79

The runner supports two execution modes with different characteristics and use cases.

80

81

#### Parallel Execution

82

83

Default mode that executes tests across multiple worker processes for optimal performance.

84

85

```typescript

86

// Parallel execution (default)

87

await runner.runTests(tests, watcher, { serial: false });

88

```

89

90

**Features:**

91

- Uses `jest-worker` to spawn worker processes

92

- Configurable worker count via `globalConfig.maxWorkers`

93

- Memory limit enforcement with `workerIdleMemoryLimit`

94

- Automatic worker cleanup and graceful shutdown

95

- Real-time progress reporting through worker communication

96

97

#### Serial Execution

98

99

Single-threaded execution mode that runs tests one by one in the main process.

100

101

```typescript

102

// Serial execution

103

await runner.runTests(tests, watcher, { serial: true });

104

// Sets process.env.JEST_WORKER_ID = '1'

105

```

106

107

**Features:**

108

- Runs in main process with `JEST_WORKER_ID = '1'`

109

- Simplified debugging and error reporting

110

- No worker process overhead

111

- Sequential test execution with rate limiting

112

113

### Event System

114

115

The runner emits typed events throughout test execution for real-time monitoring and integration.

116

117

```typescript { .api }

118

// Available events from TestEvents interface

119

type TestEvents = {

120

'test-file-start': [Test];

121

'test-file-success': [Test, TestResult];

122

'test-file-failure': [Test, SerializableError];

123

// Additional events may be forwarded from test frameworks

124

};

125

```

126

127

**Event Flow:**

128

1. `test-file-start` - Emitted when a test file begins execution

129

2. `test-file-success` - Emitted when a test file completes successfully

130

3. `test-file-failure` - Emitted when a test file fails or throws an error

131

132

### Worker Process Management

133

134

The parallel execution mode uses sophisticated worker management for optimal performance.

135

136

**Worker Configuration:**

137

- Worker count controlled by `globalConfig.maxWorkers`

138

- Memory limits enforced via `workerIdleMemoryLimit`

139

- Worker threads support via `globalConfig.workerThreads`

140

- Retry logic with up to 3 attempts per test

141

- Graceful shutdown with force-exit detection

142

143

**Worker Communication:**

144

- Bidirectional communication between main process and workers

145

- Real-time event forwarding from workers to main process

146

- Serialized context and configuration data transmission

147

- Custom message handling via `UNSTABLE_onCustomMessage`

148

149

### Error Handling and Interruption

150

151

The runner provides robust error handling and graceful interruption support.

152

153

**Interruption Handling:**

154

```typescript

155

// Watcher-based interruption

156

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

157

watcher.on('change', (state) => {

158

if (state.interrupted) {

159

// Tests will be cancelled gracefully

160

}

161

});

162

```

163

164

**Error Management:**

165

- Individual test failures don't stop the entire run

166

- Worker process crashes are handled with retries

167

- Memory leaks are detected and reported

168

- Graceful cleanup on interruption or completion

169

170

## Types

171

172

```typescript { .api }

173

interface Test {

174

path: string;

175

context: TestContext;

176

}

177

178

interface TestContext {

179

config: Config.ProjectConfig;

180

moduleMap: ModuleMap;

181

resolver: Resolver;

182

}

183

184

interface TestResult {

185

numFailingTests: number;

186

numPassingTests: number;

187

numPendingTests: number;

188

numTodoTests: number;

189

perfStats: TestPerformanceStats;

190

testFilePath: string;

191

console: ConsoleBuffer;

192

leaks: boolean;

193

// Additional properties for coverage, memory usage, etc.

194

}

195

196

interface SerializableError {

197

message: string;

198

stack?: string;

199

type: string;

200

code?: string;

201

}

202

```