BlogHome

Passing command-line arguments to pytest

2023-05-30

While working on converting ledmon tests to pytest, I stumbled upon a problem of passing command-line arguments to pytest.

Single argument

Generally it can be done by creating special file conftest.py in the tests directory of your project.

import pytest
import logging

def pytest_addoption(parser):
    parser.addoption("--my-param", action="store", default="default_value")

def pytest_generate_tests(metafunc):
    param_value = metafunc.config.option.my_param
    if 'my_param' in metafunc.fixturenames and param_value is not None:
        metafunc.parametrize("my_param", [param_value])

Along with an example_test.py

import logging

LOGGER = logging.getLogger(__name__)

def test_example_parameter(my_param):
    LOGGER.info(f'My param was passed: {my_param}')

With it all setup you can just run

$ pytest tests --log-cli-level info --my-param supervalue

and it should print out the value we provided.

List of arguments

Sometimes there might arise the need to pass an unspecified number of arguments. I found out you can pass a list of values separated by comma as one of the arguments.

import pytest
import logging

def pytest_addoption(parser):
    parser.addoption("--my-list", action="store", default="")

def pytest_generate_tests(metafunc):
    list_value = metafunc.config.option.my_list
    if 'my_list' in metafunc.fixturenames and list_value is not None:
        metafunc.parametrize("my_list", [list_value.split(",")])

Then in test example_test.py

import logging

LOGGER = logging.getLogger(__name__)

def test_example_list(my_list):
    for item in my_list:
        LOGGER.info(f'List item was passed: {item}')

It can be run with

$ pytest tests --log-cli-level info --my-list=a,b,c

And that's how argument lists can be passed to pytest.