Files
hatchet/sdks/python/examples/unit_testing/test_unit.py
Matt Kaye f1f276f6dc Feat: Python task unit tests (#1990)
* feat: add mock run methods for tasks

* feat: docs

* feat: first pass at unit tests

* cleanup: split out tests

* feat: pass lifespan through

* fix: rm comment

* drive by: retry on 404 to help with races

* chore: changelog

* chore: ver

* feat: improve logging everywhere

* chore: changelog

* fix: rm print cruft

* feat: print statement linter

* feat: helper for getting result of a standalone

* feat: docs for mock run

* feat: add task run getter

* feat: propagate additional metadata properly

* chore: gen

* fix: date

* chore: gen

* feat: return exceptions

* chore: gen

* chore: changelog

* feat: tests + gen again

* fix: rm print cruft
2025-07-17 13:54:40 -04:00

97 lines
2.6 KiB
Python

import pytest
from examples.unit_testing.workflows import (
Lifespan,
UnitTestInput,
UnitTestOutput,
async_complex_workflow,
async_simple_workflow,
async_standalone,
durable_async_complex_workflow,
durable_async_simple_workflow,
durable_async_standalone,
durable_sync_complex_workflow,
durable_sync_simple_workflow,
durable_sync_standalone,
start,
sync_complex_workflow,
sync_simple_workflow,
sync_standalone,
)
from hatchet_sdk import Task
@pytest.mark.parametrize(
"func",
[
sync_standalone,
durable_sync_standalone,
sync_simple_workflow,
durable_sync_simple_workflow,
sync_complex_workflow,
durable_sync_complex_workflow,
],
)
def test_simple_unit_sync(func: Task[UnitTestInput, UnitTestOutput]) -> None:
input = UnitTestInput(key="test_key", number=42)
additional_metadata = {"meta_key": "meta_value"}
lifespan = Lifespan(mock_db_url="sqlite:///:memory:")
retry_count = 1
expected_output = UnitTestOutput(
key=input.key,
number=input.number,
additional_metadata=additional_metadata,
retry_count=retry_count,
mock_db_url=lifespan.mock_db_url,
)
assert (
func.mock_run(
input=input,
additional_metadata=additional_metadata,
lifespan=lifespan,
retry_count=retry_count,
parent_outputs={start.name: expected_output.model_dump()},
)
== expected_output
)
@pytest.mark.parametrize(
"func",
[
async_standalone,
durable_async_standalone,
async_simple_workflow,
durable_async_simple_workflow,
async_complex_workflow,
durable_async_complex_workflow,
],
)
@pytest.mark.asyncio(loop_scope="session")
async def test_simple_unit_async(func: Task[UnitTestInput, UnitTestOutput]) -> None:
input = UnitTestInput(key="test_key", number=42)
additional_metadata = {"meta_key": "meta_value"}
lifespan = Lifespan(mock_db_url="sqlite:///:memory:")
retry_count = 1
expected_output = UnitTestOutput(
key=input.key,
number=input.number,
additional_metadata=additional_metadata,
retry_count=retry_count,
mock_db_url=lifespan.mock_db_url,
)
assert (
await func.aio_mock_run(
input=input,
additional_metadata=additional_metadata,
lifespan=lifespan,
retry_count=retry_count,
parent_outputs={start.name: expected_output.model_dump()},
)
== expected_output
)