How to pass arguments in pytest by command line
Solution 1:
In your pytest test, don't use @pytest.mark.parametrize
:
def test_print_name(name):
print ("Displaying name: %s" % name)
In conftest.py
:
def pytest_addoption(parser):
parser.addoption("--name", action="store", default="default name")
def pytest_generate_tests(metafunc):
# This is called for every test. Only get/set command line arguments
# if the argument is specified in the list of test "fixturenames".
option_value = metafunc.config.option.name
if 'name' in metafunc.fixturenames and option_value is not None:
metafunc.parametrize("name", [option_value])
Then you can run from the command line with a command line argument:
pytest -s tests/my_test_module.py --name abc
Solution 2:
Use the pytest_addoption
hook function in conftest.py
to define a new option.
Then use pytestconfig
fixture in a fixture of your own to grab the name.
You can also use pytestconfig
from a test to avoid having to write your own fixture, but I think having the option have it's own name is a bit cleaner.
# conftest.py
def pytest_addoption(parser):
parser.addoption("--name", action="store", default="default name")
# test_param.py
import pytest
@pytest.fixture()
def name(pytestconfig):
return pytestconfig.getoption("name")
def test_print_name(name):
print(f"\ncommand line param (name): {name}")
def test_print_name_2(pytestconfig):
print(f"test_print_name_2(name): {pytestconfig.getoption('name')}")
# in action
$ pytest -q -s --name Brian test_param.py
test_print_name(name): Brian
.test_print_name_2(name): Brian
.
Solution 3:
I stumbled here looking for how to pass an argument, but I wanted to avoid parameterizing the test. The answers above do perfectly well address the exact question of parameterizing a test from the command line, but I would like to offer an alternative way to pass a command line argument to particular tests. The method below uses a fixture and skips the test if the fixture is specified but the argument is not:
test.py:
def test_name(name):
assert name == 'almond'
conftest.py:
import pytest
def pytest_addoption(parser):
parser.addoption("--name", action="store")
@pytest.fixture(scope='session')
def name(request):
name_value = request.config.option.name
if name_value is None:
pytest.skip()
return name_value
Examples:
$ py.test tests/test.py
=========================== test session starts ============================
platform linux -- Python 3.7.1, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
rootdir: /home/ipetrik/dev/pytest_test, inifile:
collected 1 item
tests/test.py s [100%]
======================== 1 skipped in 0.06 seconds =========================
$ py.test tests/test.py --name notalmond
=========================== test session starts ============================
platform linux -- Python 3.7.1, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
rootdir: /home/ipetrik/dev/pytest_test, inifile:
collected 1 item
tests/test.py F [100%]
================================= FAILURES =================================
________________________________ test_name _________________________________
name = 'notalmond'
def test_name(name):
> assert name == 'almond'
E AssertionError: assert 'notalmond' == 'almond'
E - notalmond
E ? ---
E + almond
tests/test.py:5: AssertionError
========================= 1 failed in 0.28 seconds =========================
$ py.test tests/test.py --name almond
=========================== test session starts ============================
platform linux -- Python 3.7.1, pytest-4.0.0, py-1.7.0, pluggy-0.8.0
rootdir: /home/ipetrik/dev/pytest_test, inifile:
collected 1 item
tests/test.py . [100%]
========================= 1 passed in 0.03 seconds =========================
Solution 4:
All you have to do is use pytest_addoption()
in conftest.py
and finally use request
fixture:
# conftest.py
from pytest import fixture
def pytest_addoption(parser):
parser.addoption(
"--name",
action="store"
)
@fixture()
def name(request):
return request.config.getoption("--name")
And now you can run your test
def my_test(name):
assert name == 'myName'
using:
pytest --name myName