<@ULVA73B9P> I want to test a flow and its tasks, ...
# marvin-ai
f
@Marvin I want to test a flow and its tasks, without having to mock a prefect backend. I understand that calling flow.fn() will only run the flow underlying function. But how about its tasks, will they also run as simple functions, or be hooked to the prefect backend?
m
thought for 89.0 seconds
Short answer: when you call
flow.fn()
, any
@task
calls inside that flow run as plain Python functions. They will not create task runs, won’t talk to a Prefect backend, and none of the Prefect runtime features (retries, caching, timeouts, task state,
get_run_logger()
, etc.) are active. Recommended testing patterns: - Unit test tasks as pure functions:
Copy code
@task
  def add(x, y):
      return x + y

  def test_add_unit():
      assert add.fn(1, 2) == 3
- Unit test flows without Prefect orchestration:
Copy code
@flow
  def pipeline():
      return add(1, 2)

  def test_pipeline_unit():
      assert pipeline.fn() == 3  # tasks inside run as plain functions
- Lightweight integration tests (exercise Prefect engine without a backend): - Call
pipeline()
(not
.fn()
), but ensure your test environment is not configured with an API URL. In Prefect 3.x, if you haven’t set an API URL, local runs won’t hit any backend. - Practically, run tests under a Prefect profile that does not set
PREFECT_API_URL
(or unset it in your test environment). Notes/caveats when using `.fn()`: - No retries, caching, timeouts, or concurrency — it’s just Python. - Calls to
get_run_logger()
or anything that requires a flow/task run context will not work. Docs: - How to test Prefect workflows: Testing workflows in Prefect 3 If you want, I can show a pytest fixture pattern that temporarily unsets
PREFECT_API_URL
for integration-style tests.