https://prefect.io logo
Title
p

Pete Fein

02/22/2020, 3:42 PM
How do you unit test flows? I didn't see anything about it in the documentation...
j

Jeff Brainerd

02/22/2020, 4:06 PM
We unit test using the LocalExecutor and
flow.run()
. Then we examine the resulting state of the flow run to verify tasks succeeded or skipped appropriately. We also implemented a dry run mode that avoids running the guts of long running tasks.
:upvote: 2
c

Chris White

02/22/2020, 11:52 PM
There are a few other layers of testing you can do as well: - you can unit test your task logic by calling
task.run()
directly with the appropriate kwargs - you can unit test your task trigger / state change logic by creating a
TaskRunner
and calling
run
with any collection of upstream state objects (https://docs.prefect.io/api/latest/engine/task_runner.html) - you can unit test your full flow logic by providing a (possibly incomplete) dictionary of
{task: state}
pairs and providing it to
flow.run(task_states=mocked_states)
and inspecting the outputs as @Jeff Brainerd mentions above - you can unit test your schedules by testing your flow’s
schedule
class directly If there is another type of testing that you had in mind let me know and I can tell you how we would address it; this is also a good reminder that we should write a tutorial on testing flows!
s

Stanley Yeh

04/11/2020, 7:44 AM
Maybe I missed something, but I did not find any documentation on how to test code written within the Prefect framework. Googling "ValueError: Could not infer an active Flow context" did not provide much hint as to how to remedy the situation. It turns out (figured out only after reading your response here, and thanks a lot), once you decorated a function with "@task", you can no longer call it directly but had to treat it as an object and call its "run" function.
@task
def boring_func(a):
return a + 5
def test_boring_func():
assert 5 == boring_func(0)  # would not work. "ValueError: Could not infer an active Flow context"
assert 5 == boring_func.run(0)  # this would work
Wish this is mentioned somewhere in the docs.
👍 1