Parametrized fixture based on configuration file #9830
|
Hi folks, I would like to be able to test multiple embedded boards at the same time using a configuration file. My idea was to have at the end something like that: # config.yaml
devices:
- name: board_one
tty_port: /dev/ttyUSB0
- name: board_two
tty_port: /dev/ttyUSB1# test_a.py
import pytest
def test_one():
pass
@pytest.mark.not_board_one
def test_two():
passTo do this I have started a local plugin like this: # conftest.py
import pytest
import yaml
config = dict()
devices = list()
def pytest_configure(config):
# Get 'config_file' from ini or options
read_config(config_file)
def read_config(config_files):
global config
global devices
for config_file in config_files:
with open(config_file, "r") as stream:
config = yaml.safe_load(stream)
for device in config.get("devices", []):
devices.append(Device(**device))
class Device:
def __init__(self, name, tty_port):
self.name = name
self.tty_port = tty_port
def get_devices():
global devices
return devices
@pytest.fixture(scope="session", params=get_devices(), autouse=True)
def device(request):
return request.paramI did it like this because I would like to have my test to run on all boards. But I do not want to have the My idea was to later add some # conftest.py
@pytest.fixture(scope="session")
def tty_port(device):
return device.tty_port
@pytest.fixture(scope="session")
def serial(tty_port):
# Open and configure a serial link using the tty_port
return serial
# test_b.py
def test_three(serial):
# Do some serial communicationsBut this is not working... I have an error like this: Clearly the Is it possible to do something like that ? What will be the correct way to do it ? Parsing the yaml in the Thanks in advance. |
Replies: 1 comment 1 reply
|
Hi @jmlemetayer The reason For parameters derived from pytest configuration, use For example: @pytest.fixture(scope="session")
def device(request):
# Expensive setup can happen here.
return connect_to_device(request.param)
def pytest_generate_tests(metafunc):
if "device" in metafunc.fixturenames:
config_file = metafunc.config.getoption("--config-file")
devices = load_device_descriptions(config_file)
metafunc.parametrize(
"device",
devices,
indirect=True,
scope="session",
ids=lambda d: d.name,
)Then: def test_something(device):
...The important separation is:
That also avoids opening hardware/resources just to collect the test suite. Please mark this answer as accepted if it helped, thank you. |
Hi @jmlemetayer
The reason
params=get_devices()is empty is that the fixture decorator is evaluated while the module/plugin is being imported. Your devices are only populated later inpytest_configure.For parameters derived from pytest configuration, use
pytest_generate_tests, which runs during collection and has access tometafunc.config.For example: