web-dev-qa-db-fra.com

Comment passer des arguments dans pytest en ligne de commande

J'ai un code et j'ai besoin de passer les arguments tels que name from terminal. Voici mon code et comment passer les arguments. Je reçois un type d'erreur "Fichier non trouvé" que je ne comprends pas.

J'ai essayé la commande dans le terminal: pytest <filename>.py -almonds Je devrais avoir le nom imprimé comme "amandes"

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

Dans votre test pytest, n'utilisez pas @pytest.mark.parametrize:

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

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

Ensuite, vous pouvez exécuter depuis la ligne de commande avec un argument de ligne de commande:

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

Utilisez le pytest_addoption fonction de hook dans conftest.py pour définir une nouvelle option.
Ensuite, utilisez pytestconfig dans un appareil à vous pour saisir le nom.
Vous pouvez également utiliser pytestconfig à partir d’un test pour éviter d’écrire votre propre appareil, mais je pense qu’avoir l’option son propre nom est un peu plus propre.

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

J'ai trébuché ici en cherchant comment passer un argument, mais je voulais éviter de paramétrer le test. Les réponses ci-dessus répondent parfaitement à la question exacte du paramétrage d'un test à partir de la ligne de commande, mais j'aimerais proposer un autre moyen de passer un argument de ligne de commande à des tests particuliers. La méthode ci-dessous utilise une fixture et ignore le test si la fixture est spécifiée mais que l'argument n'est pas:

# 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

Exemples:

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

Selon le document officiel , le décorateur de la marque devrait ressembler à ce qui suit.

@pytest.mark.parametrize("arg1", ["StackOverflow"])
def test_mark_arg1(arg1):
    assert arg1 == "StackOverflow" #Success
    assert arg1 == "ServerFault" #Failed

Exécuter

python -m pytest <filename>.py
  • Note1: le nom de la fonction doit commencer par test_
  • Remarque2: pytest redirigera stdout (print), si vous exécutez directement stdout, vous ne pourrez afficher aucun résultat à l'écran. En outre, il n'est pas nécessaire d'imprimer le résultat dans votre fonction dans les cas de test.
  • Note3: pytest est un module exécuté par python, qui ne peut pas obtenir directement sys.argv

Si vous voulez vraiment sortir des arguments configurables, vous devriez les implémenter dans votre script. (Par exemple, chargement du contenu du fichier)

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

Transmettre des valeurs différentes à une fonction de test, en fonction des options de la ligne de commande
Supposons que nous voulions écrire un test qui dépend d’une option de ligne de commande. Voici un modèle de base pour y parvenir:

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

ref: https://docs.pytest.org/fr/latest/example/simple.html#pass-different-values-to-a-test-function-depending-on-command-line-options

Ensuite, vous pouvez l'appeler avec:

pytest --cmdopt type1
1
Mohamed.Abdo