or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# pytest-lazy-fixture

1

2

A pytest plugin that enables the use of fixtures within `pytest.mark.parametrize` decorators through lazy evaluation. This plugin solves the limitation where fixtures cannot normally be used directly in parametrize decorators by providing a lazy evaluation mechanism that resolves fixture values at test runtime.

3

4

## Package Information

5

6

- **Package Name**: pytest-lazy-fixture

7

- **Language**: Python

8

- **Installation**: `pip install pytest-lazy-fixture`

9

- **Requirements**: pytest>=3.2.5

10

11

## Core Imports

12

13

```python

14

import pytest

15

# The plugin automatically makes lazy_fixture available via pytest namespace

16

pytest.lazy_fixture('fixture_name')

17

```

18

19

Direct import:

20

21

```python

22

from pytest_lazyfixture import lazy_fixture, is_lazy_fixture, LazyFixture

23

```

24

25

## Basic Usage

26

27

```python

28

import pytest

29

30

# Define a fixture with parameters

31

@pytest.fixture(params=[1, 2])

32

def one(request):

33

return request.param

34

35

# Use lazy_fixture in parametrize to reference the fixture

36

@pytest.mark.parametrize('arg1,arg2', [

37

('val1', pytest.lazy_fixture('one')),

38

('val2', pytest.lazy_fixture('one')),

39

])

40

def test_func(arg1, arg2):

41

assert arg2 in [1, 2]

42

43

# Multiple lazy fixtures in one parametrize

44

@pytest.fixture(params=[3, 4])

45

def two(request):

46

return request.param

47

48

@pytest.mark.parametrize('arg1,arg2,arg3', [

49

('val1', pytest.lazy_fixture('one'), pytest.lazy_fixture('two')),

50

])

51

def test_multiple(arg1, arg2, arg3):

52

assert arg2 in [1, 2]

53

assert arg3 in [3, 4]

54

55

# Use in fixture parameters (indirect parametrization)

56

@pytest.fixture(params=[

57

pytest.lazy_fixture('one'),

58

pytest.lazy_fixture('two')

59

])

60

def combined(request):

61

return request.param

62

63

def test_combined(combined):

64

assert combined in [1, 2, 3, 4]

65

```

66

67

## Architecture

68

69

The pytest-lazy-fixture plugin uses pytest's hook system to intercept and modify test collection and execution. The core design enables lazy evaluation through several key components:

70

71

### Hook Integration

72

- **pytest_configure()**: Registers `lazy_fixture` function in pytest namespace for convenient access

73

- **pytest_runtest_setup()**: Modifies test request object to handle lazy fixture resolution during setup

74

- **pytest_fixture_setup()**: Resolves lazy fixtures used as parameters to other fixtures

75

- **pytest_generate_tests()**: Normalizes test generation to expand lazy fixture combinations

76

77

### Lazy Evaluation Mechanism

78

The plugin defers fixture resolution until test runtime rather than collection time:

79

1. **Collection Phase**: LazyFixture objects store fixture names without resolving values

80

2. **Setup Phase**: Plugin hooks intercept test setup and replace LazyFixture objects with actual fixture values

81

3. **Execution Phase**: Tests receive fully resolved fixture values transparently

82

83

### Dependency Resolution

84

- **Dependency Tracking**: Analyzes fixture dependency chains to ensure correct resolution order

85

- **Parameter Expansion**: Handles parametrized fixtures by expanding all combinations of lazy fixture values

86

- **Metafunction Modification**: Modifies pytest's internal test generation to support lazy fixture combinations

87

88

This design allows fixtures to be used in `@pytest.mark.parametrize` decorators while maintaining pytest's normal fixture dependency resolution and scoping rules.

89

90

## Capabilities

91

92

### Lazy Fixture Creation

93

94

Creates lazy fixture references that are resolved at test runtime rather than collection time.

95

96

```python { .api }

97

def lazy_fixture(names):

98

"""

99

Create lazy fixture references for use in parametrize decorators.

100

101

Args:

102

names (str or list): Single fixture name or list of fixture names

103

104

Returns:

105

LazyFixture or list[LazyFixture]: Lazy fixture wrapper(s)

106

"""

107

```

108

109

Usage examples:

110

111

```python

112

# Single fixture

113

lazy_ref = pytest.lazy_fixture('my_fixture')

114

115

# Multiple fixtures

116

lazy_refs = lazy_fixture(['fixture1', 'fixture2'])

117

```

118

119

### Lazy Fixture Detection

120

121

Utility function to check if a value is a lazy fixture instance.

122

123

```python { .api }

124

def is_lazy_fixture(val):

125

"""

126

Check if a value is a LazyFixture instance.

127

128

Args:

129

val: Value to check

130

131

Returns:

132

bool: True if val is a LazyFixture instance

133

"""

134

```

135

136

Usage example:

137

138

```python

139

if is_lazy_fixture(some_value):

140

# Handle lazy fixture

141

actual_value = request.getfixturevalue(some_value.name)

142

```

143

144

### Lazy Fixture Wrapper

145

146

The core wrapper class that holds fixture names for lazy evaluation.

147

148

```python { .api }

149

class LazyFixture(object):

150

"""

151

Wrapper class for lazy fixture evaluation.

152

153

Attributes:

154

name (str): Name of the fixture to be resolved

155

"""

156

157

def __init__(self, name):

158

"""

159

Initialize lazy fixture with fixture name.

160

161

Args:

162

name (str): Name of the fixture to wrap

163

"""

164

165

def __repr__(self):

166

"""

167

String representation of the lazy fixture.

168

169

Returns:

170

str: Formatted string showing class name and fixture name

171

"""

172

173

def __eq__(self, other):

174

"""

175

Compare LazyFixture instances by fixture name.

176

177

Args:

178

other (LazyFixture): Another LazyFixture instance

179

180

Returns:

181

bool: True if fixture names are equal

182

"""

183

```

184

185

### Plugin Integration

186

187

The plugin automatically integrates with pytest through entry points and hooks:

188

189

```python { .api }

190

# Available after plugin installation

191

pytest.lazy_fixture # Function accessible via pytest namespace

192

```

193

194

## Plugin Features

195

196

### Parametrize Integration

197

198

- **Direct parametrization**: Use lazy fixtures as parameter values in `@pytest.mark.parametrize`

199

- **Multiple fixtures**: Support for multiple lazy fixtures in the same parametrize decorator

200

- **Mixed parameters**: Combine lazy fixtures with regular values in parametrize

201

202

### Indirect Parametrization

203

204

- **Fixture parameters**: Use lazy fixtures as parameters to other fixtures

205

- **Fixture chains**: Support for fixtures that depend on other fixtures through lazy evaluation

206

207

### Test ID Generation

208

209

- **Automatic naming**: Test IDs automatically use fixture names for lazy fixtures

210

- **Clear identification**: Easy identification of which fixture values are being tested

211

212

### Dependency Resolution

213

214

- **Automatic resolution**: Lazy fixtures are resolved automatically at test runtime

215

- **Dependency order**: Proper handling of fixture dependency chains

216

- **Parameter sorting**: Internal sorting to ensure fixtures are resolved in correct order

217

218

## Internal Implementation Details

219

220

The plugin works by:

221

222

1. **Hook Integration**: Registers pytest hooks to intercept test collection and execution

223

2. **Lazy Evaluation**: Defers fixture resolution until test runtime using `request.getfixturevalue()`

224

3. **Metafunction Modification**: Modifies pytest's metafunction calls to handle lazy fixtures

225

4. **Dependency Tracking**: Tracks and resolves fixture dependencies in correct order

226

227

Key internal functions (not part of public API):

228

229

- `pytest_runtest_setup()`: Modifies test setup to handle lazy fixtures

230

- `pytest_fixture_setup()`: Resolves lazy fixtures used as fixture parameters

231

- `pytest_generate_tests()`: Normalizes test generation for lazy fixtures

232

- `sorted_by_dependency()`: Ensures fixtures are resolved in dependency order

233

234

## Error Handling

235

236

The plugin handles various pytest version compatibility issues and provides appropriate error handling for:

237

238

- Missing fixtures referenced by lazy_fixture

239

- Circular fixture dependencies

240

- Version compatibility across pytest 3.2.5+ releases

241

242

## Compatibility

243

244

- **Python**: 2.7, 3.4+

245

- **pytest**: 3.2.5+

246

- **Platforms**: Cross-platform (Windows, macOS, Linux)

247

- **Implementation**: CPython, PyPy