or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-ddt

Data-Driven/Decorated Tests - A library to multiply test cases

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/ddt@1.7.x

To install, run

npx @tessl/cli install tessl/pypi-ddt@1.7.0

0

# DDT (Data-Driven Tests)

1

2

A Python library that allows you to multiply one test case by running it with different test data, making it appear as multiple test cases. DDT provides decorators that transform unittest test methods into data-driven tests, enabling systematic validation of functionality across diverse input conditions.

3

4

## Package Information

5

6

- **Package Name**: ddt

7

- **Package Type**: pypi

8

- **Language**: Python

9

- **Installation**: `pip install ddt`

10

- **Documentation**: http://ddt.readthedocs.org/

11

12

## Core Imports

13

14

```python

15

from ddt import ddt, data, file_data, unpack, idata, named_data, TestNameFormat

16

```

17

18

Or using the module directly:

19

20

```python

21

import ddt

22

```

23

24

## Basic Usage

25

26

```python

27

import unittest

28

from ddt import ddt, data, file_data, unpack, TestNameFormat

29

30

@ddt

31

class MyTestCase(unittest.TestCase):

32

33

@data(1, 2, 3, 4)

34

def test_simple_values(self, value):

35

self.assertTrue(value > 0)

36

37

@data([1, 2], [3, 4], [5, 6])

38

@unpack

39

def test_with_unpack(self, a, b):

40

self.assertLess(a, b)

41

42

@file_data('test_data.json')

43

def test_with_file_data(self, value):

44

self.assertIsNotNone(value)

45

46

@ddt(testNameFormat=TestNameFormat.INDEX_ONLY)

47

class IndexOnlyTestCase(unittest.TestCase):

48

49

@data("hello", "world")

50

def test_with_index_only_names(self, value):

51

self.assertIsInstance(value, str)

52

53

if __name__ == '__main__':

54

unittest.main()

55

```

56

57

## Capabilities

58

59

### Class Decorator

60

61

#### ddt Decorator

62

63

Enables data-driven testing on unittest.TestCase subclasses.

64

65

```python { .api }

66

def ddt(arg=None, **kwargs):

67

"""

68

Class decorator for test cases that enables data-driven testing.

69

70

Parameters:

71

- arg: unittest.TestCase subclass or None (for parameterized decorator usage)

72

- **kwargs: Optional configuration parameters

73

- testNameFormat: TestNameFormat enum value for controlling test name generation

74

75

Returns:

76

Decorated test class with generated test methods

77

"""

78

```

79

80

### Method Decorators

81

82

#### data Decorator

83

84

Provides test data values directly to test methods.

85

86

```python { .api }

87

def data(*values):

88

"""

89

Method decorator to provide test data values.

90

91

Parameters:

92

- *values: Variable number of test data values

93

94

Returns:

95

Decorated test method that runs once per data value

96

"""

97

```

98

99

#### idata Decorator

100

101

Provides test data from an iterable with optional index formatting.

102

103

```python { .api }

104

def idata(iterable, index_len=None):

105

"""

106

Method decorator to provide test data from an iterable.

107

108

Parameters:

109

- iterable: Iterable of test data values

110

- index_len: Optional integer specifying width to zero-pad test indices

111

112

Returns:

113

Decorated test method that runs once per iterable item

114

"""

115

```

116

117

#### file_data Decorator

118

119

Loads test data from JSON or YAML files.

120

121

```python { .api }

122

def file_data(value, yaml_loader=None):

123

"""

124

Method decorator to load test data from files.

125

126

Parameters:

127

- value: Path to JSON/YAML file relative to test file directory

128

- yaml_loader: Optional custom YAML loader function

129

130

Returns:

131

Decorated test method that runs with file-based data

132

"""

133

```

134

135

#### unpack Decorator

136

137

Unpacks tuple/list/dict test data as separate function arguments.

138

139

```python { .api }

140

def unpack(func):

141

"""

142

Method decorator to unpack structured test data.

143

144

Parameters:

145

- func: Test method to be decorated

146

147

Returns:

148

Decorated test method that unpacks data arguments

149

"""

150

```

151

152

#### named_data Decorator

153

154

Provides meaningful names to data-driven tests.

155

156

```python { .api }

157

def named_data(*named_values):

158

"""

159

Method decorator to provide named test data with meaningful test names.

160

161

Parameters:

162

- *named_values: Sequences or dictionaries with 'name' key for test identification

163

164

Returns:

165

Decorated test method with named test cases

166

"""

167

```

168

169

### Utility Functions

170

171

#### mk_test_name Function

172

173

Generates test case names from original name, value, and index.

174

175

```python { .api }

176

def mk_test_name(name, value, index=0, index_len=5, name_fmt=TestNameFormat.DEFAULT):

177

"""

178

Generate a new name for a test case.

179

180

Parameters:

181

- name: Original test method name

182

- value: Test data value

183

- index: Test case index (default: 0)

184

- index_len: Width for zero-padding indices (default: 5)

185

- name_fmt: TestNameFormat enum value for name formatting

186

187

Returns:

188

str: Generated test case name

189

"""

190

```

191

192

#### is_trivial Function

193

194

Determines if a value is a simple/scalar type for name generation.

195

196

```python { .api }

197

def is_trivial(value):

198

"""

199

Check if value is a trivial type for test naming.

200

201

Parameters:

202

- value: Value to check

203

204

Returns:

205

bool: True if value is trivial (scalar or simple container)

206

"""

207

```

208

209

### Configuration

210

211

#### TestNameFormat Enum

212

213

Controls how test names are generated.

214

215

```python { .api }

216

class TestNameFormat(Enum):

217

"""

218

Enum to configure test name composition.

219

220

Values:

221

- DEFAULT (0): Include both index and value in test name

222

- INDEX_ONLY (1): Include only index in test name

223

"""

224

DEFAULT = 0

225

INDEX_ONLY = 1

226

```

227

228

### Helper Classes

229

230

#### _NamedDataList Class

231

232

List subclass with name attribute for test naming (used internally by named_data).

233

234

```python { .api }

235

class _NamedDataList(list):

236

"""

237

List subclass with name attribute for meaningful test names.

238

239

Parameters:

240

- name: Name for the test case

241

- *args: List elements

242

"""

243

def __init__(self, name, *args): ...

244

def __str__(self): ...

245

```

246

247

#### _NamedDataDict Class

248

249

Dict subclass with name attribute for test naming (used internally by named_data).

250

251

```python { .api }

252

class _NamedDataDict(dict):

253

"""

254

Dict subclass with name attribute for meaningful test names.

255

256

Parameters:

257

- **kwargs: Dictionary items including required 'name' key

258

259

Raises:

260

- KeyError: If 'name' key is not provided

261

"""

262

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

263

def __str__(self): ...

264

```

265

266

### Constants

267

268

#### __version__

269

270

Package version string.

271

272

```python { .api }

273

__version__ = "1.7.2"

274

```

275

276

## Types

277

278

```python { .api }

279

import unittest

280

from typing import Union, Any, List, Dict, Type, Callable

281

282

# Type aliases for documentation

283

TestData = Union[Any, List[Any], Dict[str, Any]]

284

TestMethod = Callable[..., None]

285

TestClass = Type[unittest.TestCase]

286

```

287

288

## Usage Examples

289

290

### Multiple Data Values

291

292

```python

293

@ddt

294

class TestCalculator(unittest.TestCase):

295

296

@data(2, 4, 6, 8)

297

def test_even_numbers(self, value):

298

self.assertEqual(value % 2, 0)

299

```

300

301

### Complex Data with Unpacking

302

303

```python

304

@ddt

305

class TestMath(unittest.TestCase):

306

307

@data((2, 3, 5), (1, 1, 2), (0, 5, 5))

308

@unpack

309

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

310

self.assertEqual(a + b, expected)

311

```

312

313

### File-Based Data

314

315

```python

316

# test_data.json

317

[

318

{"input": "hello", "expected": 5},

319

{"input": "world", "expected": 5}

320

]

321

322

@ddt

323

class TestStringLength(unittest.TestCase):

324

325

@file_data('test_data.json')

326

def test_length(self, value):

327

input_str = value['input']

328

expected = value['expected']

329

self.assertEqual(len(input_str), expected)

330

```

331

332

### Named Data for Better Test Names

333

334

```python

335

@ddt

336

class TestAPI(unittest.TestCase):

337

338

@named_data(

339

['valid_user', 'john@example.com', 200],

340

['invalid_email', 'invalid-email', 400],

341

['empty_email', '', 400]

342

)

343

def test_user_creation(self, email, expected_status):

344

response = create_user(email)

345

self.assertEqual(response.status_code, expected_status)

346

```

347

348

### YAML Data with Custom Loader

349

350

```python

351

import yaml

352

353

# Custom YAML loader for loading specific data types

354

class CustomLoader(yaml.SafeLoader):

355

pass

356

357

def construct_custom_object(loader, node):

358

return {'type': 'custom', 'value': loader.construct_scalar(node)}

359

360

CustomLoader.add_constructor('!custom', construct_custom_object)

361

362

@ddt

363

class TestYAMLData(unittest.TestCase):

364

365

@file_data('test_data.yaml', yaml_loader=CustomLoader)

366

def test_yaml_with_custom_loader(self, value):

367

self.assertIn('type', value)

368

self.assertEqual(value['type'], 'custom')

369

```

370

371

Example `test_data.yaml` file:

372

```yaml

373

- !custom "test_value_1"

374

- !custom "test_value_2"

375

- !custom "test_value_3"

376

```