This is the runnable companion to the Testing Hamilton code how-to. It shows that Hamilton functions are normal Python -- so the standard pytest patterns you already know apply, including when decorators are involved.
The example covers the four cases from issue #1044:
test_my_functions.pytest_decorated_functions.pyinputs= and overrides= -- test_driver.pyad_hoc_utils.create_temporary_module -- test_ad_hoc_module.py| File | Purpose |
|---|---|
my_functions.py | A small marketing dataflow (no decorators). |
decorated_functions.py | The same style of dataflow, using @tag, @parameterize and @extract_columns. |
test_my_functions.py | Unit tests that import and call functions directly. |
test_decorated_functions.py | Unit + driver-level tests for the decorated module. |
test_driver.py | End-to-end tests using Builder().with_modules(...).build() plus inputs= and overrides=. |
test_ad_hoc_module.py | Builds a module from inline-defined functions for self-contained tests. |
conftest.py | Adds this folder to sys.path so import my_functions works under pytest. |
pip install -r requirements.txt pytest
You should see all tests pass. Each test file is independently runnable:
pytest test_my_functions.py -v pytest test_driver.py -v
@tag, @parameterize, @extract_columns, ...) leave the underlying callable intact. Direct function calls still work; the decorator changes how Hamilton wires the function into the DAG, not what the function computes.Builder().with_modules(...).build() is the canonical entry point. Use inputs= to inject test data at the DAG inputs and overrides= to short-circuit intermediate nodes when you want to assert on downstream logic in isolation..py file on disk? Use hamilton.ad_hoc_utils.create_temporary_module.If you have questions, or need help with this example, join us on Slack.