Как передать аргументы в pytest по командной строке

У меня есть код, и мне нужно передать аргументы, такие как имя из терминала. Вот мой код и как передать аргументы. Я получаю ошибку типа "Файл не найден", которую не понимаю.

Я пробовал команду в терминале: pytest <filename>.py -almonds Я должен получить имя, напечатанное как "миндаль"

@pytest.mark.parametrize("name")
def print_name(name):
    print ("Displaying name: %s" % name)

Ответ 1

В своем тесте pytest не используйте @pytest.mark.parametrize:

def test_print_name(name):
    print ("Displaying name: %s" % name)

В 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])

Затем вы можете запустить из командной строки с аргументом командной строки:

pytest -s tests/my_test_module.py --name abc

Ответ 2

Используйте pytest_addoption ловушки pytest_addoption в conftest.py чтобы определить новую опцию.
Затем используйте приспособление pytestconfig в собственном приспособлении, чтобы получить имя.
Вы также можете использовать pytestconfig из теста, чтобы избежать необходимости писать свой собственный прибор, но я думаю, что вариант с собственным именем немного чище.

# 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
.

Ответ 3

Я споткнулся здесь, ища, как передать аргумент, но я хотел избежать параметризации теста. Приведенные выше ответы прекрасно подходят для точного определения параметров теста из командной строки, но я хотел бы предложить альтернативный способ передачи аргумента командной строки в конкретные тесты. Приведенный ниже метод использует прибор и пропускает тест, если прибор указан, но аргумент - нет:

# test.py
def test_name(name):
    assert name == 'almond'


# conftest.py
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

Примеры:

$ 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 =========================

Ответ 4

Согласно официальному документу

Run

python -m pytest <filename>.py
Примечание1: имя функции должно начинаться с test_ Примечание2: pytest перенаправит stdout (print), поэтому прямое выполнение stdout не сможет показать результат на экране. Кроме того, нет необходимости печатать результат в вашей функции в тестовых случаях. Note3: pytest - это модуль, выполняемый python, который не может напрямую получить sys.argv.

Если вы действительно хотите получить внешние настраиваемые аргументы, вы должны реализовать это внутри своего script. (Например, загрузка содержимого файла)

with open("arguments.txt") as f:
    args = f.read().splitlines()
...
@pytest.mark.parametrize("arg1", args)
...

Ответ 5

  Передавать в тестовую функцию разные значения в зависимости от параметров командной строки
Предположим, мы хотим написать тест, который зависит от параметра командной строки. Вот основной шаблон для достижения этой цели:

# 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")

ссылка: https://docs.pytest.org/en/latest/example/simple.html#pass-different-values-to-a-test-function-depending-on-command-line-options

Тогда вы можете позвонить с помощью:

pytest --cmdopt type1

Ответ 6

Если вы привыкли к argparse, вы можете подготовить его обычным способом на 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.