{"id":3453,"library":"ddt","title":"Data-Driven/Decorated Tests","description":"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.","status":"active","version":"1.7.2","language":"python","source_language":"en","source_url":"https://github.com/datadriventests/ddt","tags":["testing","unittest","data-driven","decorators"],"install":[{"cmd":"pip install ddt","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"The 'ddt' class decorator must be imported directly from the module, not the module itself.","wrong":"import ddt","symbol":"ddt","correct":"from ddt import ddt"},{"symbol":"data","correct":"from ddt import data"},{"symbol":"unpack","correct":"from ddt import unpack"},{"symbol":"file_data","correct":"from ddt import file_data"},{"symbol":"named_data","correct":"from ddt import named_data"}],"quickstart":{"code":"import unittest\nfrom ddt import ddt, data, unpack\n\n@ddt\nclass MyTests(unittest.TestCase):\n\n    @data(1, 2, 3)\n    def test_single_value(self, value):\n        self.assertGreater(value, 0)\n\n    @data((1, 2), (3, 4))\n    @unpack\n    def test_multiple_values(self, a, b):\n        self.assertLess(a, b)\n\n    # Example with named_data (requires ddt >= 1.5.0)\n    # from ddt import named_data\n    # @named_data(  \n    #     {'name': 'test_case_one', 'x': 5, 'y': 10},\n    #     {'name': 'test_case_two', 'x': 10, 'y': 5}\n    # )\n    # def test_with_named_data(self, x, y):\n    #     self.assertGreater(x, y)\n\nif __name__ == '__main__':\n    unittest.main()","lang":"python","description":"This quickstart demonstrates basic usage of `ddt` with `unittest`. It shows how to use the `@ddt` class decorator and the `@data` and `@unpack` method decorators to run the same test logic with different inputs. The commented-out section shows usage of `@named_data` for more descriptive test names."},"warnings":[{"fix":"Upgrade to Python 3 or pin ddt to `<1.7.0`.","message":"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.","severity":"breaking","affected_versions":">=1.7.0"},{"fix":"Upgrade to Python 3.6+ or pin ddt to `<1.5.0`.","message":"ddt dropped support for Python 3.5 in version 1.5.0.","severity":"breaking","affected_versions":">=1.5.0"},{"fix":"Ensure your test runner (e.g., `unittest.main()` or `pytest`) is configured correctly, and remove any `nose`-specific configurations related to `ddt`.","message":"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.","severity":"breaking","affected_versions":">=1.4.1"},{"fix":"Set the `PYTHONHASHSEED` environment variable to a fixed value (e.g., `export PYTHONHASHSEED=1`) before running tests, or use the `@named_data` decorator (introduced in 1.5.0) for explicit test naming.","message":"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.","severity":"gotcha","affected_versions":"all (Python 3.3+)"},{"fix":"Rename your test file to something other than `ddt.py`, for example, `test_my_feature.py`.","message":"Naming your test file `ddt.py` will cause an `ImportError` because Python will try to import your local file instead of the `ddt` library.","severity":"gotcha","affected_versions":"all"},{"fix":"Only use `@unpack` when your `@data` values are tuples/lists that correspond to multiple test method arguments, or dictionaries for keyword arguments. If your test method expects a single argument, do not use `@unpack`.","message":"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.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"search_vec":"'/decorated':4 '1.7.2':53 'activ':58 'allow':30 'cadenc':60 'case':38 'current':50 'data':2,8,18,27,43,67 'data-driven':1,7,17,66 'ddt':6 'decor':22,69 'differ':42 'driven':3,9,19,68 'effici':46 'enabl':16 'enhanc':44 'librari':14 'maintain':56 'method':24,34 'multipl':36 'multipli':31 'one':32 'python':13 'readabl':48 'regular':62 'releas':59 'run':40 'sourc':28 'test':5,10,20,23,37,45,64 'unittest':65 'unittest.testcase':33 'updat':63 'various':26 'version':51","created_at":"2026-04-11T17:29:45.899633+00:00","updated_at":"2026-04-16T05:55:58.098226+00:00","problems":[{"fix":"If you have a file named `ddt.py` in your project or Python path, rename it to something else (e.g., `my_tests.py`). Ensure your import statement is `from ddt import ddt, data, unpack` (or only the decorators you need), and decorate your test class with `@ddt`.","cause":"This error typically occurs when a local Python file is named `ddt.py`, shadowing the installed `ddt` library, or when attempting to import the `ddt` decorator incorrectly using `import ddt` instead of `from ddt import ddt`.","error":"ImportError: cannot import name 'ddt'"},{"fix":"Ensure that the data provided to `ddt` decorators is always an iterable. Validate that any function or file providing data returns a list, tuple, or dictionary (even an empty one) and not `None`.","cause":"This error happens when the data source provided to `ddt` decorators like `@data` or `@file_data` resolves to `None` instead of an iterable (e.g., a list, tuple, or dictionary). This can occur if a function fetching the test data returns `None` unexpectedly.","error":"TypeError: 'NoneType' object is not iterable"},{"fix":"To run a specific data-driven test, use the full, `ddt`-generated test name, which typically includes an index and a string representation of the data. For example: `python -m unittest your_module.YourTestCaseClass.test_method_1_data_value`. Alternatively, run the entire test class to allow `ddt` to discover and execute all generated tests.","cause":"When running individual data-driven tests from the command line, `unittest` expects the full, `ddt`-generated test method name (e.g., `test_method_1_data_value`), not the original base method name defined in your test class. `ddt` dynamically creates these unique test methods during test discovery.","error":"AttributeError: type object 'YourTestCaseClass' has no attribute 'your_test_method_name'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.7.2","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/datadriventests/ddt","docs":null,"changelog":null,"pypi":"https://pypi.org/project/ddt/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}