Say I have two sets of test data for a BDD scenario.
dataX = [A, B, C]
dataY = [1, 2, 3, 4]
How can I run a scenario against all combinations of dataX-dataY, without explicitly defining these combinations in the scenario outline?
Currently, the BDD scenario looks something like the below, and as you can see I am explicitly defining all possible combinations. Things can become very impractical very quickly if the value count and/or variable count increase. Am using the python-behave library
for this.
Scenario Outline: Test all data combinations - <dataX> <dataY>
Given combination <dataX> <dataY>
When do stuff with given combination <dataX> <dataY>
Then check result for <dataX> <dataY>
Examples: Input
| dataX | dataY |
| A | 1 |
| A | 2 |
| A | 3 |
| A | 4 |
| B | 1 |
| B | 2 |
| B | 3 |
| B | 4 |
| C | 1 |
| C | 2 |
| C | 3 |
| C | 4 |
Note this needs to be done via Scenario Outline & Examples to ensure all test data coverage. Using a simple Scenario and potentially testing all combinations under a single test is not sufficient, as it typically means the test stops at the first failure encountered, skipping any remaining test data.
After going through the guts of the behave
library implementation, I was able to find some methods that one can use to do just this: build the Examples
table programatically. My use case is the large number of data combinations that all need testing.
This goes in environment.py
:
from behave.model import Scenario, Examples, Table
from itertools import product
def before_feature(context, feature):
...
# data for each column for the Examples table; the way you get this is based on your specific case;
# you can read it from a file or generate it etc.; this here is merely an example
data_x = [data for test column dataX here]
data_y = [data for test column dataY here]
# create data tuples aka table rows; we will add these a bit later to the Examples table
# the way you build this is also specific to your case; I am using itertools.product for a quick way to get all possible pairs
all_data_pairs = [(dx, dy) for dx, dy in product(data_x, data_y)]
# identify the behave.model.Examples object we will populate
example: Examples = next(sc.examples[0] for sc in feature.scenarios if
sc.name == 'Test all data combinations - <dataX> <dataY>')
# Examples consists, amongst other things, of an object of type behave.model.Table
test_table: Table = example.table
# add test data to the Examples table, row by row
for row in all_data_pairs:
test_table.add_row(row)
This will ensure scenario "Test all data combinations - <dataX> <dataY>"
asserts all test rows. It will NOT stop after the first failure.