
* Rework Pipeline.run() tests * Remove test_linear_pipeline.py * Add test for components execution order * Add new pytest-bdd tests dependency * Update README.md * Add function to dinamically add integration marker * Fix marking tests as integration
Pipeline.run()
behavioural tests
This module contains all behavioural tests for Pipeline.run()
.
pipeline_run.feature
contains the definition of the tests using a subset of the Gherkin language. It's not the full language because we're using pytest-bdd
and it doesn't implement it in full, but it's good enough for our use case. For more info see the project README.md
.
There are two cases covered by these tests:
Pipeline.run()
returns some outputPipeline.run()
raises an exception
Correct Pipeline
In the first case to add a new test you need add a new entry in the Examples
of the Running a correct Pipeline
scenario outline and create the corresponding step that creates the Pipeline
you need to test.
For example to add a test for a linear Pipeline
I add a new that is linear
kind in pipeline_run.feature
.
Scenario Outline: Running a correct Pipeline
Given a pipeline <kind>
When I run the Pipeline
Then it should return the expected result
Examples:
| kind |
| that has no components |
| that is linear |
Then define a new pipeline_that_is_linear
function in test_run.py
.
The function must be decorated with @given
and return a tuple containing the Pipeline
instance, the Pipeline.run()
inputs, the expected output and the expected Components run order, in this exact order.
The @given
arguments must be the full step name, "a pipeline that is linear"
in this case, and target_fixture
must be set to "pipeline_data"
.
@given("a pipeline that is linear", target_fixture="pipeline_data")
def pipeline_that_is_linear():
pipeline = Pipeline()
pipeline.add_component("first_addition", AddFixedValue(add=2))
pipeline.add_component("second_addition", AddFixedValue())
pipeline.add_component("double", Double())
pipeline.connect("first_addition", "double")
pipeline.connect("double", "second_addition")
return (
pipeline,
{"first_addition": {"value": 1}},
{"second_addition": {"result": 7}},
["first_addition", "double", "second_addition"],
)
Bad Pipeline
The second case is similar to the first one, but we can also specify the expected exception.
In this case we test that a Pipeline
with an infinite loop raises PipelineMaxLoops
.
Scenario Outline: Running a bad Pipeline
Given a pipeline <kind>
When I run the Pipeline
Then it must have raised <exception>
Examples:
| kind | exception |
| that has an infinite loop | PipelineMaxLoops |
In a similar way as first case we need to defined a new pipeline_that_has_an_infinite_loop
function in test_run.py
, with some small differences.
The only difference from the first case is the last value returned by the function, in this case we return the expected exception class.
@given("a pipeline that has an infinite loop", target_fixture="pipeline_data")
def pipeline_that_has_an_infinite_loop():
def custom_init(self):
component.set_input_type(self, "x", int)
component.set_input_type(self, "y", int, 1)
component.set_output_types(self, a=int, b=int)
FakeComponent = component_class("FakeComponent", output={"a": 1, "b": 1}, extra_fields={"__init__": custom_init})
pipe = Pipeline(max_loops_allowed=1)
pipe.add_component("first", FakeComponent())
pipe.add_component("second", FakeComponent())
pipe.connect("first.a", "second.x")
pipe.connect("second.b", "first.y")
return pipe, {"first": {"x": 1}}, PipelineMaxLoops