After much experimentation I finally found how to do it. What I needed was to pass user name and password to my script in order to allow the code to log into a test server. My test looked like this:
my_module_test.py
import pytest
import my_module
def login_test(username, password):
instance = my_module.Login(username, password)
# ...more...
conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption('--username', action='store', help='Repository user')
parser.addoption('--password', action='store', help='Repository password')
def pytest_generate_tests(metafunc):
username = metafunc.config.option.username
if 'username' in metafunc.fixturenames and username is not None:
metafunc.parametrize('username', [username])
password = metafunc.config.option.password
if 'password' in metafunc.fixturenames and password is not None:
metafunc.parametrize('password', [password])
Then in my settings file I can use:
.vscode/settings.json
{
// ...more...
"python.testing.autoTestDiscoverOnSaveEnabled": true,
"python.testing.unittestEnabled": false,
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.pytestArgs": [
"--exitfirst",
"--verbose",
"test/",
"--username=myname",
"--password=secret",
// ...more...
],
}
An alternative way is to use pytest.ini file instead:
pytest.ini
[pytest]
junit_family=legacy
addopts = --username=myname --password=secret
If this is just for the debugger then you can specify things in "args" in your launch.json file. See https://code.visualstudio.com/docs/python/debugging#_args for more details.
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(scope="session")
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
.
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