or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdconfiguration.mdfixtures.mdindex.mdmarks.mdreporting.mdtest-collection.mdtest-utilities.mdtesting-functions.mdwarnings.md

configuration.mddocs/

0

# Configuration and Plugin System

1

2

Central configuration management and plugin architecture enabling extensive customization through hooks, configuration files, command-line options, and the pluggy-based plugin system.

3

4

## Capabilities

5

6

### Configuration Management

7

8

Central configuration object providing access to all pytest settings and options.

9

10

```python { .api }

11

class Config:

12

"""Central configuration object with access to pluginmanager and hooks."""

13

14

# Core attributes

15

pluginmanager: PytestPluginManager # Plugin manager instance

16

invocation_params: InvocationParams # Command-line invocation parameters

17

option: argparse.Namespace # Parsed command-line options

18

rootpath: Path # Root directory path

19

inipath: Path | None # Path to configuration file

20

21

def getini(self, name: str) -> Any:

22

"""

23

Get configuration value from ini file.

24

25

Parameters:

26

- name: Configuration option name

27

28

Returns:

29

Configuration value

30

"""

31

32

def getoption(self, name: str, default=None, skip: bool = False) -> Any:

33

"""

34

Get command-line option value.

35

36

Parameters:

37

- name: Option name

38

- default: Default value if option not set

39

- skip: Whether to skip if option not found

40

41

Returns:

42

Option value

43

"""

44

45

def addinivalue_line(self, name: str, line: str) -> None:

46

"""

47

Add line to multi-line ini configuration value.

48

49

Parameters:

50

- name: Configuration option name

51

- line: Line to add

52

"""

53

54

def issue_config_time_warning(self, warning: Warning, stacklevel: int) -> None:

55

"""Issue warning during configuration time."""

56

```

57

58

### Plugin Management

59

60

Plugin manager extending pluggy with pytest-specific functionality for loading and managing plugins.

61

62

```python { .api }

63

class PytestPluginManager:

64

"""Extends pluggy.PluginManager with pytest-specific functionality."""

65

66

def register(self, plugin, name: str | None = None) -> None:

67

"""

68

Register a plugin instance.

69

70

Parameters:

71

- plugin: Plugin instance

72

- name: Optional plugin name

73

"""

74

75

def unregister(self, plugin=None, name: str | None = None) -> Any:

76

"""

77

Unregister a plugin instance.

78

79

Parameters:

80

- plugin: Plugin instance to unregister

81

- name: Plugin name to unregister

82

83

Returns:

84

Unregistered plugin

85

"""

86

87

def get_plugin(self, name: str):

88

"""Get plugin by name."""

89

90

def is_registered(self, plugin) -> bool:

91

"""Check if plugin is registered."""

92

93

def list_plugin_distinfo(self) -> list[tuple[Any, DistInfo]]:

94

"""List all plugin distribution info."""

95

96

def list_name_plugin(self) -> list[tuple[str, Any]]:

97

"""List all plugins with their names."""

98

99

def get_canonical_name(self, plugin) -> str:

100

"""Get canonical name for plugin."""

101

102

def load_setuptools_entrypoints(self, group: str, names: str | None = None) -> int:

103

"""Load plugins from setuptools entry points."""

104

105

def consider_env(self, name: str, value: str | None = None) -> None:

106

"""Consider environment variable for plugin loading."""

107

108

def consider_preparse(self, args: list[str], exclude_only: bool = False) -> None:

109

"""Consider command-line arguments for plugin loading."""

110

111

def consider_conftest(self, conftestmodule) -> None:

112

"""Register hooks from conftest module."""

113

```

114

115

### Hook System

116

117

Decorators for marking functions as hook implementations and specifications.

118

119

```python { .api }

120

def hookimpl(**kwargs):

121

"""

122

Mark function as hook implementation.

123

124

Parameters:

125

- tryfirst: Execute this hook first

126

- trylast: Execute this hook last

127

- hookwrapper: Hook wrapper (can yield)

128

- optionalhook: Hook is optional

129

- specname: Name of hook specification

130

131

Returns:

132

HookimplMarker decorator

133

"""

134

135

def hookspec(**kwargs):

136

"""

137

Mark function as hook specification.

138

139

Parameters:

140

- firstresult: Return first non-None result

141

- historic: Historic hook (replay for late registrations)

142

- warn_on_impl: Issue warnings for implementations

143

144

Returns:

145

HookspecMarker decorator

146

"""

147

```

148

149

**Usage Example:**

150

151

```python

152

import pytest

153

154

# Plugin implementation

155

class MyPlugin:

156

@pytest.hookimpl(tryfirst=True)

157

def pytest_configure(self, config):

158

print("Configuring my plugin")

159

160

@pytest.hookimpl

161

def pytest_collection_modifyitems(self, config, items):

162

# Modify collected test items

163

pass

164

165

@pytest.hookimpl(hookwrapper=True)

166

def pytest_runtest_setup(self, item):

167

print(f"Setting up {item.name}")

168

outcome = yield

169

print(f"Setup complete for {item.name}")

170

171

# Register plugin

172

def pytest_configure(config):

173

config.pluginmanager.register(MyPlugin(), "myplugin")

174

```

175

176

### Argument Parsing

177

178

Command-line argument parser for pytest with support for options and ini values.

179

180

```python { .api }

181

class Parser:

182

"""Command-line argument parser for pytest."""

183

184

def addoption(

185

self,

186

*names,

187

action=None,

188

nargs=None,

189

const=None,

190

default=None,

191

type=None,

192

choices=None,

193

required=None,

194

help=None,

195

metavar=None,

196

dest=None,

197

**kwargs

198

) -> None:

199

"""Add command-line option."""

200

201

def getgroup(self, name: str, description: str = "") -> OptionGroup:

202

"""Get or create option group."""

203

204

def addini(

205

self,

206

name: str,

207

help: str,

208

type: str | None = None,

209

default=None,

210

**kwargs

211

) -> None:

212

"""Add ini file configuration option."""

213

214

class OptionGroup:

215

"""Groups related command-line options."""

216

217

def addoption(self, *names, **kwargs) -> None:

218

"""Add option to this group."""

219

220

def _addoption(self, *names, **kwargs) -> None:

221

"""Internal method to add option."""

222

```

223

224

**Usage Example:**

225

226

```python

227

# In conftest.py or plugin

228

def pytest_addoption(parser):

229

parser.addoption(

230

"--myopt",

231

action="store",

232

default="default",

233

help="My custom option"

234

)

235

236

group = parser.getgroup("mygroup", "My custom options")

237

group.addoption(

238

"--verbose-mode",

239

action="store_true",

240

help="Enable verbose mode"

241

)

242

243

parser.addini(

244

"my_setting",

245

help="My configuration setting",

246

type="string",

247

default="default_value"

248

)

249

250

def pytest_configure(config):

251

my_opt = config.getoption("myopt")

252

my_setting = config.getini("my_setting")

253

```

254

255

### Exit Codes

256

257

Enumeration of pytest exit codes for different execution outcomes.

258

259

```python { .api }

260

from enum import IntEnum

261

262

class ExitCode(IntEnum):

263

"""Integer enum for pytest exit codes."""

264

265

OK = 0 # All tests passed

266

TESTS_FAILED = 1 # One or more tests failed

267

INTERRUPTED = 2 # Test run interrupted

268

INTERNAL_ERROR = 3 # Internal pytest error

269

USAGE_ERROR = 4 # Command-line usage error

270

NO_TESTS_RAN = 5 # No tests found/collected

271

```

272

273

### Configuration Exceptions

274

275

```python { .api }

276

class UsageError(Exception):

277

"""

278

Raised for command-line usage errors.

279

280

This exception is raised when:

281

- Invalid command-line arguments are provided

282

- Required options are missing

283

- Option values are invalid

284

"""

285

```

286

287

## Entry Points

288

289

Main entry points for running pytest programmatically.

290

291

```python { .api }

292

def main(args=None, plugins=None) -> int:

293

"""

294

Main entry point for running pytest programmatically.

295

296

Parameters:

297

- args: Command-line arguments (defaults to sys.argv)

298

- plugins: List of plugin objects to register

299

300

Returns:

301

Exit code (ExitCode enum value)

302

"""

303

304

def console_main() -> int:

305

"""

306

Console script entry point.

307

Called by pytest command-line script.

308

309

Returns:

310

Exit code

311

"""

312

313

# Module-level entry point

314

import pytest.config.cmdline

315

316

def cmdline.main() -> int:

317

"""Command line interface entry point."""

318

```

319

320

## Configuration Files

321

322

pytest supports multiple configuration file formats:

323

324

```python

325

# pytest.ini

326

[tool:pytest]

327

addopts = -v --tb=short

328

testpaths = tests

329

python_files = test_*.py *_test.py

330

python_classes = Test*

331

python_functions = test_*

332

markers =

333

slow: marks tests as slow

334

integration: marks tests as integration tests

335

336

# pyproject.toml

337

[tool.pytest.ini_options]

338

addopts = "-v --tb=short"

339

testpaths = ["tests"]

340

python_files = ["test_*.py", "*_test.py"]

341

342

# setup.cfg

343

[tool:pytest]

344

addopts = -v --tb=short

345

testpaths = tests

346

```

347

348

## Hook Specifications

349

350

Comprehensive hook system for extending pytest functionality at every stage:

351

352

```python { .api }

353

# Configuration and startup hooks

354

def pytest_configure(config: Config) -> None:

355

"""Called after command line options are parsed and plugins loaded."""

356

357

def pytest_unconfigure(config: Config) -> None:

358

"""Called before test process is exited."""

359

360

def pytest_sessionstart(session: Session) -> None:

361

"""Called after Session object has been created."""

362

363

def pytest_sessionfinish(session: Session, exitstatus: int) -> None:

364

"""Called after whole test run finished."""

365

366

# Collection hooks

367

def pytest_collect_file(parent: Collector, path: Path) -> Collector | None:

368

"""Create a collector for the given path."""

369

370

def pytest_collection_modifyitems(config: Config, items: list[Item]) -> None:

371

"""Called after collection is completed to modify or re-order items."""

372

373

def pytest_generate_tests(metafunc: Metafunc) -> None:

374

"""Generate (parametrize) tests for the given function."""

375

376

# Test execution hooks

377

def pytest_runtest_setup(item: Item) -> None:

378

"""Called to perform the setup phase for a test item."""

379

380

def pytest_runtest_call(item: Item) -> None:

381

"""Called to run the test for test item."""

382

383

def pytest_runtest_teardown(item: Item, nextitem: Item | None) -> None:

384

"""Called to perform the teardown phase for a test item."""

385

386

def pytest_runtest_makereport(item: Item, call: CallInfo) -> TestReport | None:

387

"""Called to create a TestReport for each phase."""

388

389

# Fixture hooks

390

def pytest_fixture_setup(fixturedef: FixtureDef, request: FixtureRequest) -> object:

391

"""Perform fixture setup execution."""

392

393

def pytest_fixture_post_finalizer(fixturedef: FixtureDef, request: FixtureRequest) -> None:

394

"""Called after fixture teardown."""

395

396

# Reporting hooks

397

def pytest_report_teststatus(report: TestReport, config: Config) -> tuple[str, str, str] | None:

398

"""Return result-category, shortletter and verbose word for reporting."""

399

400

def pytest_terminal_summary(terminalreporter: TerminalReporter, exitstatus: int, config: Config) -> None:

401

"""Add sections to the terminal summary reporting."""

402

403

# Warning and error hooks

404

def pytest_warning_recorded(warning_message, when: str, nodeid: str, location: tuple[str, int, str]) -> None:

405

"""Process a warning captured by the internal pytest warnings plugin."""

406

407

def pytest_internalerror(excrepr: ExceptionRepr, excinfo: ExceptionInfo) -> bool:

408

"""Called for internal errors."""

409

```

410

411

## Plugin Development

412

413

```python

414

# conftest.py - Automatic plugin loading

415

def pytest_configure(config):

416

"""Called after command line options are parsed."""

417

418

def pytest_collection_modifyitems(config, items):

419

"""Called after collection is completed."""

420

421

def pytest_runtest_setup(item):

422

"""Called before each test runs."""

423

424

# External plugin package

425

from setuptools import setup

426

427

setup(

428

name="pytest-myplugin",

429

entry_points={

430

"pytest11": [

431

"myplugin = myplugin.plugin",

432

],

433

},

434

)

435

```

436

437

## Types

438

439

```python { .api }

440

from typing import Any

441

from pathlib import Path

442

443

class ExceptionRepr:

444

"""Representation of an exception for reporting purposes."""

445

446

def toterminal(self, tw: TerminalWriter) -> None:

447

"""Write exception representation to terminal."""

448

449

def __str__(self) -> str:

450

"""String representation of exception."""

451

452

class InvocationParams:

453

"""Parameters used during pytest invocation."""

454

455

# Attributes

456

args: tuple[str, ...] # Command line arguments

457

plugins: tuple[str, ...] | None # Plugin names

458

dir: Path # Working directory

459

```