or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

artifacts-files.mdassertions.mdcli.mdconfiguration.mdcontext-cleanup.mdevents.mdexecution-control.mdindex.mdparameterization.mdtest-definition.md

parameterization.mddocs/

0

# Test Parameterization

1

2

Powerful parameterization system supporting multiple parameter sets with optional decorators for enhanced functionality.

3

4

## Capabilities

5

6

### Basic Parameterization

7

8

The core `params` decorator for creating multiple test instances with different input values.

9

10

```python { .api }

11

class params:

12

"""

13

Parameterization decorator for creating multiple test instances.

14

15

Can be used as a decorator directly or with additional decorators

16

via class item access.

17

"""

18

19

def __init__(self, *args, **kwargs):

20

"""

21

Initialize parameterization with positional and keyword arguments.

22

23

Args:

24

*args: Positional arguments to pass to the test

25

**kwargs: Keyword arguments to pass to the test

26

"""

27

28

def __call__(self, fn: F) -> F:

29

"""

30

Apply parameters to the test function or class constructor.

31

32

Args:

33

fn: Function or class to parameterize

34

35

Returns:

36

The parameterized function/class

37

"""

38

39

def __class_getitem__(cls, item) -> Callable[..., Parameterized]:

40

"""

41

Create parameterization with additional decorators.

42

43

Args:

44

item: Single decorator or tuple of decorators

45

46

Returns:

47

Callable that creates Parameterized instance with decorators

48

"""

49

```

50

51

#### Usage Example - Class-based

52

53

```python

54

from vedro import Scenario, params

55

56

class Scenario(vedro.Scenario):

57

subject = "mathematical operations"

58

59

@params(2, 3, 5) # a=2, b=3, expected=5

60

@params(10, 15, 25) # a=10, b=15, expected=25

61

@params(-5, 8, 3) # a=-5, b=8, expected=3

62

def __init__(self, a, b, expected):

63

self.a = a

64

self.b = b

65

self.expected = expected

66

67

def when_numbers_are_added(self):

68

self.result = self.a + self.b

69

70

def then_result_matches_expected(self):

71

assert self.result == self.expected

72

```

73

74

#### Usage Example - Function-based

75

76

```python

77

from vedro import scenario, params, given, when, then, ensure

78

79

@params("admin", 200)

80

@params("user", 200)

81

@params("guest", 403)

82

@scenario("API access with different user roles")

83

def test_api_access(role, expected_status):

84

85

@given(f"user with {role} role")

86

def setup():

87

return authenticate_user_with_role(role)

88

89

@when("user accesses protected resource")

90

def action(user):

91

return api_request("/protected-resource", auth=user.token)

92

93

@then(f"response has status {expected_status}")

94

def verification(response):

95

ensure(response.status_code).equals(expected_status)

96

```

97

98

### Parameterization with Keywords

99

100

Support for keyword arguments in parameterization for more readable tests.

101

102

```python

103

@params(username="admin", password="admin123", should_succeed=True)

104

@params(username="user", password="wrongpass", should_succeed=False)

105

@params(username="", password="", should_succeed=False)

106

@scenario("Login with various credentials")

107

def test_login(username, password, should_succeed):

108

109

@given("login credentials")

110

def setup():

111

return {"username": username, "password": password}

112

113

@when("user attempts login")

114

def action(credentials):

115

try:

116

result = login(credentials["username"], credentials["password"])

117

return {"success": True, "result": result}

118

except AuthenticationError as e:

119

return {"success": False, "error": str(e)}

120

121

@then("login outcome matches expectation")

122

def verification(outcome):

123

ensure(outcome["success"]).equals(should_succeed)

124

```

125

126

### Parameterization with Decorators

127

128

Advanced parameterization that applies additional decorators to specific parameter sets.

129

130

```python

131

from vedro import skip

132

133

# Apply skip decorator to specific parameter sets

134

@params[skip("Flaky test")]("slow_endpoint", 30)

135

@params("fast_endpoint", 5)

136

@params("medium_endpoint", 15)

137

@scenario("API response times")

138

def test_response_times(endpoint, max_time):

139

140

@when(f"requesting {endpoint}")

141

def action():

142

start_time = time.time()

143

response = api_request(f"/api/{endpoint}")

144

duration = time.time() - start_time

145

return {"response": response, "duration": duration}

146

147

@then(f"response time is under {max_time} seconds")

148

def verification(result):

149

ensure(result["response"].status_code).equals(200)

150

ensure(result["duration"]).is_less_than(max_time)

151

```

152

153

### Multiple Decorator Application

154

155

Apply multiple decorators to parameterized tests.

156

157

```python

158

from vedro import skip_if, only

159

160

# Apply multiple decorators to parameter sets

161

@params[(skip_if(not EXTERNAL_API_AVAILABLE), only)](

162

"external_api", "https://api.external.com"

163

)

164

@params("internal_api", "http://localhost:8000")

165

@scenario("API integration tests")

166

def test_api_integration(api_name, base_url):

167

168

@when(f"calling {api_name}")

169

def action():

170

return api_request(f"{base_url}/health")

171

172

@then("API responds successfully")

173

def verification(response):

174

ensure(response.status_code).equals(200)

175

```

176

177

## Types

178

179

### Parameterized

180

181

Internal class representing a parameterized test with arguments and decorators.

182

183

```python { .api }

184

class Parameterized:

185

"""

186

Represents a parameterized function or method with stored arguments

187

and decorators that are applied when the function is invoked.

188

"""

189

190

def __init__(self, args, kwargs, decorators: Tuple): ...

191

def __call__(self, fn: F) -> F: ...

192

```

193

194

### Type Annotations

195

196

For type checking support, params provides appropriate type annotations.

197

198

```python { .api }

199

# Type-checking support

200

F = TypeVar("F", bound=Callable[..., Any])

201

ItemType = Union[Callable[[F], F], Tuple[Callable[[F], F], ...]]

202

```

203

204

## Advanced Patterns

205

206

### Complex Parameter Objects

207

208

Use complex objects as parameters for comprehensive test scenarios:

209

210

```python

211

from dataclasses import dataclass

212

213

@dataclass

214

class UserProfile:

215

name: str

216

email: str

217

role: str

218

active: bool

219

220

@params(UserProfile("John Doe", "john@example.com", "admin", True))

221

@params(UserProfile("Jane Smith", "jane@example.com", "user", True))

222

@params(UserProfile("Bob Johnson", "bob@example.com", "guest", False))

223

@scenario("User profile management")

224

def test_user_profiles(profile):

225

226

@given("user profile data")

227

def setup():

228

return profile

229

230

@when("profile is processed")

231

def action(user_profile):

232

return process_user_profile(user_profile)

233

234

@then("profile is handled correctly")

235

def verification(result):

236

if profile.active:

237

ensure(result.status).equals("processed")

238

else:

239

ensure(result.status).equals("inactive")

240

```

241

242

### Parameter Generation

243

244

Generate parameters dynamically for data-driven tests:

245

246

```python

247

# Generate test parameters from external data

248

test_cases = [

249

params(input_val, expected)

250

for input_val, expected in load_test_data("math_operations.json")

251

]

252

253

# Apply generated parameters

254

for param_decorator in test_cases:

255

@param_decorator

256

@scenario("Generated math test")

257

def test_generated_math(input_val, expected):

258

@when("calculation is performed")

259

def action():

260

return complex_calculation(input_val)

261

262

@then("result matches expected value")

263

def verification(result):

264

ensure(result).equals(expected)

265

```

266

267

### Conditional Parameterization

268

269

Skip or modify parameters based on runtime conditions:

270

271

```python

272

import sys

273

274

# Conditionally apply parameters based on Python version

275

version_params = []

276

if sys.version_info >= (3, 9):

277

version_params.append(params("python39_feature", True))

278

if sys.version_info >= (3, 10):

279

version_params.append(params("python310_feature", True))

280

281

version_params.append(params("legacy_feature", True))

282

283

for param_decorator in version_params:

284

@param_decorator

285

@scenario("Version-specific features")

286

def test_version_features(feature_name, should_work):

287

@when(f"using {feature_name}")

288

def action():

289

return test_feature(feature_name)

290

291

@then("feature works as expected")

292

def verification(result):

293

ensure(result.success).equals(should_work)

294

```