Data-Driven/Decorated Tests
ddt (Data-Driven Tests) is a Python library that enables data-driven testing by decorating test methods with various data sources. It allows multiplying one `unittest.TestCase` method into multiple test cases, each run with different data, enhancing test efficiency and readability. The current version is 1.7.2, and it maintains an active release cadence with regular updates.
Warnings
- breaking ddt dropped support for Python 2.7 in version 1.7.0. Projects using ddt with Python 2.7 must remain on an older ddt version or migrate to Python 3.
- breaking ddt dropped support for Python 3.5 in version 1.5.0.
- breaking The `nose` dependency was completely removed in version 1.4.1. This means `ddt` no longer has specific integrations or requirements for `nose`, favoring standard `unittest` or `pytest` runners.
- gotcha When using `@data` or `@file_data` with complex data types (like dictionaries or custom objects), the generated test names can be unpredictable if Python hash randomization is enabled (default in Python 3.3+). This can affect test reporting and re-running failed tests.
- gotcha Naming your test file `ddt.py` will cause an `ImportError` because Python will try to import your local file instead of the `ddt` library.
- gotcha The `@unpack` decorator is used to unpack iterable (tuples, lists) or dictionary arguments into multiple positional or keyword arguments for the test method, respectively. Misunderstanding its function can lead to `TypeError` or unexpected argument passing.
Install
-
pip install ddt
Imports
- ddt
from ddt import ddt
- data
from ddt import data
- unpack
from ddt import unpack
- file_data
from ddt import file_data
- named_data
from ddt import named_data
Quickstart
import unittest
from ddt import ddt, data, unpack
@ddt
class MyTests(unittest.TestCase):
@data(1, 2, 3)
def test_single_value(self, value):
self.assertGreater(value, 0)
@data((1, 2), (3, 4))
@unpack
def test_multiple_values(self, a, b):
self.assertLess(a, b)
# Example with named_data (requires ddt >= 1.5.0)
# from ddt import named_data
# @named_data(
# {'name': 'test_case_one', 'x': 5, 'y': 10},
# {'name': 'test_case_two', 'x': 10, 'y': 5}
# )
# def test_with_named_data(self, x, y):
# self.assertGreater(x, y)
if __name__ == '__main__':
unittest.main()