or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-line.mdcoverage-controllers.mderror-handling.mdfixtures-markers.mdindex.mdplugin-integration.mdsubprocess-support.md

fixtures-markers.mddocs/

0

# Fixtures and Markers

1

2

pytest-cov provides built-in pytest fixtures and markers that allow fine-grained control over coverage measurement at the test level. These tools enable developers to exclude specific tests from coverage or access the underlying coverage object for advanced scenarios.

3

4

## Capabilities

5

6

### Coverage Control Fixtures

7

8

Fixtures that control coverage behavior during test execution.

9

10

```python { .api }

11

@pytest.fixture

12

def no_cover():

13

"""

14

A pytest fixture to disable coverage for specific tests.

15

16

When used as a fixture parameter, disables coverage measurement

17

for the duration of the test function. The fixture itself does

18

nothing - its presence signals the coverage system to pause

19

measurement.

20

21

Usage:

22

def test_excluded_function(no_cover):

23

# This test will not be included in coverage reports

24

pass

25

"""

26

27

@pytest.fixture

28

def cov(request):

29

"""

30

A pytest fixture to provide access to the underlying coverage object.

31

32

Returns the active coverage.Coverage instance if coverage is enabled,

33

allowing tests to inspect coverage state, access configuration, or

34

perform advanced coverage operations.

35

36

Args:

37

request: pytest request object

38

39

Returns:

40

coverage.Coverage: Active coverage instance, or None if disabled

41

42

Usage:

43

def test_coverage_info(cov):

44

if cov:

45

print(f"Data file: {cov.config.data_file}")

46

print(f"Source: {cov.config.source}")

47

"""

48

```

49

50

**Usage Examples:**

51

52

```python

53

import pytest

54

55

def test_normal_coverage():

56

"""This test will be included in coverage measurement."""

57

import mymodule

58

assert mymodule.function() == "expected"

59

60

def test_excluded_with_fixture(no_cover):

61

"""This test will be excluded from coverage."""

62

import mymodule

63

# This code execution won't count toward coverage

64

mymodule.debug_function()

65

66

def test_coverage_access(cov):

67

"""Test that can access coverage configuration."""

68

if cov:

69

# Can inspect coverage settings

70

assert cov.config.data_file

71

assert hasattr(cov.config, 'source')

72

73

# Test code still gets measured for coverage

74

import mymodule

75

mymodule.function()

76

77

def test_both_fixtures(cov, no_cover):

78

"""Test using both fixtures - coverage access but no measurement."""

79

if cov:

80

print(f"Coverage enabled but test excluded")

81

# This test code won't be measured for coverage

82

```

83

84

### Coverage Control Markers

85

86

pytest markers that provide declarative coverage control.

87

88

```python { .api }

89

# Marker registration (done automatically by plugin)

90

config.addinivalue_line('markers', 'no_cover: disable coverage for this test.')

91

```

92

93

The `no_cover` marker provides an alternative to the fixture for excluding tests from coverage measurement.

94

95

**Usage Examples:**

96

97

```python

98

import pytest

99

100

@pytest.mark.no_cover

101

def test_excluded_with_marker():

102

"""This test will be excluded from coverage measurement."""

103

import mymodule

104

# Code execution here won't count toward coverage

105

mymodule.debug_function()

106

107

@pytest.mark.no_cover

108

def test_debugging_code():

109

"""Useful for tests that exercise debugging or development-only code."""

110

import mymodule

111

mymodule.internal_debug_function()

112

113

class TestDevelopmentFeatures:

114

"""Test class for development features."""

115

116

@pytest.mark.no_cover

117

def test_dev_feature_a(self):

118

"""Development feature test excluded from coverage."""

119

pass

120

121

def test_production_feature(self):

122

"""Production feature test included in coverage."""

123

pass

124

```

125

126

### Fixture Implementation Details

127

128

Internal implementation of the fixture system and coverage control.

129

130

```python { .api }

131

def cov(request):

132

"""

133

Implementation of the cov fixture.

134

135

Checks if the '_cov' plugin is registered and active, then

136

returns the coverage controller's coverage instance if available.

137

138

Returns None if:

139

- Coverage plugin is not registered

140

- Coverage plugin has no active controller

141

- Coverage controller has no coverage instance

142

"""

143

```

144

145

The fixture implementation:

146

147

1. **Plugin Detection**: Uses `pluginmanager.hasplugin('_cov')` to check if coverage is active

148

2. **Controller Access**: Gets the `CovPlugin` instance via `pluginmanager.getplugin('_cov')`

149

3. **Coverage Instance**: Returns `plugin.cov_controller.cov` if available

150

4. **Graceful Fallback**: Returns `None` if any step fails

151

152

### Marker Processing

153

154

How the coverage system processes markers and fixtures during test execution.

155

156

```python { .api }

157

def pytest_runtest_call(self, item):

158

"""

159

Process coverage control markers and fixtures during test execution.

160

161

Checks for:

162

- @pytest.mark.no_cover marker on test function

163

- 'no_cover' in test's fixture names

164

165

If either is found, pauses coverage before test execution

166

and resumes coverage after test completion.

167

"""

168

```

169

170

The marker/fixture processing logic:

171

172

```python

173

# Check for marker or fixture

174

if item.get_closest_marker('no_cover') or 'no_cover' in getattr(item, 'fixturenames', ()):

175

self.cov_controller.pause()

176

yield # Execute test

177

self.cov_controller.resume()

178

else:

179

yield # Execute test normally with coverage

180

```

181

182

## Integration Patterns

183

184

### Combining Fixtures and Markers

185

186

Different ways to control coverage in test scenarios:

187

188

```python

189

# Using marker (preferred for permanent exclusions)

190

@pytest.mark.no_cover

191

def test_debug_helper():

192

pass

193

194

# Using fixture (useful for conditional logic)

195

def test_conditional_coverage(no_cover, some_condition):

196

if some_condition:

197

# Test logic that should be excluded

198

pass

199

200

# Accessing coverage while excluding test

201

@pytest.mark.no_cover

202

def test_coverage_inspection(cov):

203

if cov:

204

print(f"Coverage active but test excluded")

205

```

206

207

### Conditional Coverage Control

208

209

Using fixtures for dynamic coverage control:

210

211

```python

212

@pytest.fixture

213

def maybe_no_cover(request):

214

"""Conditionally disable coverage based on test conditions."""

215

if request.config.getoption("--debug-mode"):

216

request.getfixturevalue("no_cover")

217

218

def test_with_conditional_coverage(maybe_no_cover):

219

"""Coverage depends on command-line flag."""

220

# Test code here

221

pass

222

```

223

224

### Coverage Inspection Patterns

225

226

Common patterns for using the `cov` fixture:

227

228

```python

229

def test_coverage_configuration(cov):

230

"""Inspect coverage configuration."""

231

if cov:

232

assert cov.config.branch is True

233

assert cov.config.source == ['mypackage']

234

235

def test_coverage_data_access(cov):

236

"""Access coverage measurement data."""

237

if cov:

238

# Get current coverage data

239

data = cov.get_data()

240

measured_files = data.measured_files()

241

assert len(measured_files) > 0

242

243

def test_coverage_reporting(cov, tmp_path):

244

"""Generate custom coverage reports."""

245

if cov:

246

# Generate custom report

247

report_file = tmp_path / "custom_report.txt"

248

with open(report_file, 'w') as f:

249

cov.report(file=f)

250

assert report_file.exists()

251

```

252

253

### Test Organization

254

255

Organizing tests with coverage control:

256

257

```python

258

class TestProductionCode:

259

"""Tests for production functionality - all measured."""

260

261

def test_feature_a(self):

262

import mymodule

263

assert mymodule.feature_a()

264

265

def test_feature_b(self):

266

import mymodule

267

assert mymodule.feature_b()

268

269

class TestDevelopmentCode:

270

"""Tests for development/debug code - excluded from coverage."""

271

272

@pytest.mark.no_cover

273

def test_debug_mode(self):

274

import mymodule

275

mymodule.enable_debug_mode()

276

277

@pytest.mark.no_cover

278

def test_development_feature(self):

279

import mymodule

280

mymodule.experimental_feature()

281

282

class TestCoverageAware:

283

"""Tests that need coverage introspection."""

284

285

def test_with_coverage_check(self, cov):

286

"""Test that verifies coverage is working."""

287

if cov:

288

# Verify coverage is measuring our module

289

import mymodule

290

mymodule.function()

291

292

data = cov.get_data()

293

assert any('mymodule' in f for f in data.measured_files())

294

```