Note2: pytest will redirect stdout (print), thus directly running stdout will not able to show any result on the screen. Also, there is no need to print result in your function in test cases.
Note3: pytest is a module run by python, which is not able to get sys.argv directly
If you really want to get outside configurable arguments, you should you implement that inside your script. (For example, loading content of file)
with open("arguments.txt") as f:
args = f.read().splitlines()
...
@pytest.mark.parametrize("arg1", args)
...
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:
I stumbled here looking for how to pass an argument, but I wanted to avoid parameterizing the test. The accepted answer does 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 =========================
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.
Pass different values to a test function, depending on command line options
Suppose we want to write a test that depends on a command line option. Here is a
basic pattern to achieve this:
# content of test_sample.py
def test_answer(cmdopt):
if cmdopt == "type1":
print("first")
elif cmdopt == "type2":
print("second")
assert 0 # to see what was printed
For this to work we need to add a command line option and provide the cmdopt through a fixture function:
# content of conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption(
"--cmdopt", action="store", default="type1", help="my option: type1 or type2"
)
@pytest.fixture
def cmdopt(request):
return request.config.getoption("--cmdopt")
If you are used to argparse, you can prepare it the usual way in arparse
import argparse
import sys
DEFAULT_HOST = test99
#### for --host parameter ###
def pytest_addoption(parser):
parser.addoption("--host") # needed otherwhise --host will fail pytest
parser = argparse.ArgumentParser(description="run test on --host")
parser.add_argument('--host', help='host to run tests on (default: %(default)s)', default=DEFAULT_HOST)
args, notknownargs = parser.parse_known_args()
if notknownargs:
print("pytest arguments? : {}".format(notknownargs))
sys.argv[1:] = notknownargs
#
then args.hosts holds you variable, while sys.args is parsed further with pytest.