or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mddjango-integration.mdindex.mdjunit-xml.mdoutput-formatting.mdsetuptools-integration.mdtest-execution.mdtest-loading.mdtest-results.md

test-execution.mddocs/

0

# Test Execution

1

2

Green's test execution system provides multi-process parallel test running with process pool management, worker initialization, and comprehensive test orchestration for improved performance.

3

4

## Capabilities

5

6

### Main Test Runner

7

8

The core function that orchestrates test execution with Green's enhanced features including parallel processing, coverage integration, and result aggregation.

9

10

```python { .api }

11

def run(suite, stream, args, testing=False):

12

"""

13

Run tests with Green's enhanced features.

14

15

Args:

16

suite: Test suite to run (GreenTestSuite or unittest.TestSuite)

17

stream: Output stream, will be wrapped in GreenStream if not already

18

args: Configuration namespace containing execution parameters:

19

- processes: Number of parallel processes (0 = auto-detect)

20

- run_coverage: Enable coverage reporting

21

- initializer: Worker process initializer function

22

- finalizer: Worker process finalizer function

23

- debug: Debug level for execution details

24

testing (bool): Enable testing mode behavior (affects coverage and output)

25

26

Returns:

27

GreenTestResult: Comprehensive test execution results with:

28

- Individual test outcomes

29

- Timing information

30

- Coverage data (if enabled)

31

- Process execution statistics

32

33

Example:

34

from green.runner import run

35

from green.loader import GreenTestLoader

36

from green.output import GreenStream

37

from green.config import get_default_args

38

import sys

39

40

# Load tests

41

loader = GreenTestLoader()

42

suite = loader.loadTargets(['tests/'])

43

44

# Configure execution

45

args = get_default_args()

46

args.processes = 4

47

args.run_coverage = True

48

49

# Run tests

50

stream = GreenStream(sys.stdout)

51

result = run(suite, stream, args)

52

53

print(f"Tests run: {result.testsRun}")

54

print(f"Success: {result.wasSuccessful()}")

55

"""

56

```

57

58

### Worker Process Management

59

60

Helper class for managing worker process initialization and cleanup functions.

61

62

```python { .api }

63

class InitializerOrFinalizer:

64

"""

65

Manages worker process setup and teardown functions.

66

67

Allows specifying custom initialization and cleanup code that runs

68

in each worker process before and after test execution.

69

"""

70

71

def __init__(self, dotted_function):

72

"""

73

Initialize with a dotted function name.

74

75

Args:

76

dotted_function (str): Fully qualified function name like

77

'mymodule.setup_function' or

78

'mypackage.tests.init_worker'

79

80

Example:

81

initializer = InitializerOrFinalizer('tests.setup.init_database')

82

finalizer = InitializerOrFinalizer('tests.setup.cleanup_database')

83

"""

84

85

def __call__(self, *args):

86

"""

87

Execute the configured function.

88

89

Args:

90

*args: Arguments to pass to the function

91

92

Raises:

93

InitializerOrFinalizerError: If function cannot be loaded or executed

94

"""

95

```

96

97

## Usage Examples

98

99

### Basic Test Execution

100

101

```python

102

from green.runner import run

103

from green.loader import GreenTestLoader

104

from green.output import GreenStream

105

from green.config import parseArguments, mergeConfig

106

import sys

107

108

# Load and configure

109

args = parseArguments(['tests/'])

110

config = mergeConfig(args)

111

112

loader = GreenTestLoader()

113

suite = loader.loadTargets(config.targets)

114

115

# Execute tests

116

stream = GreenStream(sys.stdout)

117

result = run(suite, stream, config)

118

119

# Check results

120

if result.wasSuccessful():

121

print("All tests passed!")

122

exit(0)

123

else:

124

print(f"Tests failed: {len(result.failures)} failures, {len(result.errors)} errors")

125

exit(1)

126

```

127

128

### Parallel Execution Configuration

129

130

```python

131

from green.runner import run

132

from green.config import get_default_args

133

134

# Configure parallel execution

135

args = get_default_args()

136

args.processes = 8 # Use 8 processes

137

args.debug = 1 # Enable debug output

138

139

# Auto-detect optimal process count

140

args.processes = 0 # Green will use multiprocessing.cpu_count()

141

142

# Single-process execution (useful for debugging)

143

args.processes = 1

144

```

145

146

### Custom Worker Initialization

147

148

```python

149

from green.runner import run, InitializerOrFinalizer

150

from green.config import get_default_args

151

152

# Create worker setup functions

153

def setup_test_database():

154

"""Initialize test database connection in worker process."""

155

import sqlite3

156

global db_connection

157

db_connection = sqlite3.connect(':memory:')

158

# Setup test tables, etc.

159

160

def cleanup_test_database():

161

"""Clean up test database in worker process."""

162

global db_connection

163

if db_connection:

164

db_connection.close()

165

166

# Configure with initializer/finalizer

167

args = get_default_args()

168

args.initializer = 'tests.setup.setup_test_database'

169

args.finalizer = 'tests.setup.cleanup_test_database'

170

171

# The InitializerOrFinalizer will be used internally

172

result = run(suite, stream, args)

173

```

174

175

### Coverage Integration

176

177

```python

178

from green.runner import run

179

from green.config import get_default_args

180

181

# Enable coverage

182

args = get_default_args()

183

args.run_coverage = True

184

args.coverage_config_file = '.coveragerc' # Custom coverage config

185

args.omit_patterns = ['*/tests/*', '*/venv/*'] # Patterns to omit

186

187

result = run(suite, stream, args)

188

189

# Coverage data will be automatically collected and reported

190

```

191

192

### Debug Mode Execution

193

194

```python

195

from green.runner import run

196

from green.config import get_default_args

197

198

# Enable detailed debug output

199

args = get_default_args()

200

args.debug = 2 # Higher debug levels provide more detail

201

args.processes = 1 # Single process for easier debugging

202

203

result = run(suite, stream, args)

204

```

205

206

### Error Handling and Recovery

207

208

```python

209

from green.runner import run

210

from green.exceptions import InitializerOrFinalizerError

211

212

try:

213

result = run(suite, stream, args)

214

215

# Check for various error conditions

216

if result.errors:

217

print(f"Test errors occurred: {len(result.errors)}")

218

for test, error in result.errors:

219

print(f" {test}: {error}")

220

221

if result.failures:

222

print(f"Test failures occurred: {len(result.failures)}")

223

for test, failure in result.failures:

224

print(f" {test}: {failure}")

225

226

except InitializerOrFinalizerError as e:

227

print(f"Worker process setup failed: {e}")

228

# Handle worker initialization errors

229

230

except KeyboardInterrupt:

231

print("Test execution interrupted by user")

232

# Handle Ctrl+C gracefully

233

234

except Exception as e:

235

print(f"Unexpected error during test execution: {e}")

236

# Handle other execution errors

237

```

238

239

### Advanced Execution Scenarios

240

241

```python

242

from green.runner import run

243

from green.suite import GreenTestSuite

244

from green.config import get_default_args

245

246

# Custom test suite configuration

247

suite = GreenTestSuite()

248

# Add tests to suite...

249

250

# Configure for specific execution environment

251

args = get_default_args()

252

253

# CI/CD environment

254

if os.environ.get('CI'):

255

args.processes = 0 # Auto-detect

256

args.run_coverage = True

257

args.junit_report = 'test-results.xml'

258

args.verbose = 1 # Minimal output for CI logs

259

260

# Development environment

261

else:

262

args.processes = 2 # Don't overwhelm development machine

263

args.verbose = 2 # More verbose for development

264

args.debug = 1 # Enable debug output

265

266

result = run(suite, stream, args)

267

```

268

269

### Integration with Custom Test Frameworks

270

271

```python

272

from green.runner import run

273

from green.loader import GreenTestLoader

274

import unittest

275

276

class CustomTestResult(unittest.TestResult):

277

"""Custom result processor."""

278

pass

279

280

# Green can work with custom test frameworks

281

loader = GreenTestLoader()

282

suite = loader.loadTargets(['tests/'])

283

284

# Green will handle the parallel execution and result aggregation

285

result = run(suite, stream, args)

286

287

# Post-process results with custom logic

288

custom_processor = CustomTestResult()

289

# Process results as needed...

290

```

291

292

## Process Pool Management

293

294

Green uses a custom process pool implementation for enhanced parallel execution:

295

296

### Features

297

- **Daemonless Processes**: Workers can spawn their own subprocesses

298

- **Custom Finalizers**: Clean shutdown of worker processes

299

- **Enhanced Logging**: Better error reporting from worker processes

300

- **Coverage Integration**: Automatic coverage data collection from workers

301

- **Signal Handling**: Graceful handling of interruption signals

302

303

### Configuration Options

304

305

```python

306

# Process count options

307

args.processes = 0 # Auto-detect (multiprocessing.cpu_count())

308

args.processes = 1 # Single process (no parallelization)

309

args.processes = 4 # Specific process count

310

args.processes = -1 # Use all available CPUs

311

312

# Worker customization

313

args.initializer = 'module.setup_function' # Run in each worker on startup

314

args.finalizer = 'module.cleanup_function' # Run in each worker on shutdown

315

```

316

317

## Performance Considerations

318

319

### Optimal Process Count

320

- **CPU-bound tests**: processes = cpu_count()

321

- **I/O-bound tests**: processes = cpu_count() * 2

322

- **Memory-intensive tests**: processes = cpu_count() / 2

323

- **Development/debugging**: processes = 1

324

325

### Test Organization for Parallelization

326

- Group related tests in the same module

327

- Avoid shared state between test methods

328

- Use fixtures for test data setup/teardown

329

- Consider process-local resources (databases, files)

330

331

### Coverage Overhead

332

- Coverage adds ~20-30% execution time

333

- Benefits from parallel execution

334

- Use `.coveragerc` to optimize data collection

335

- Consider coverage sampling for very large test suites