web-dev-qa-db-ja.com

コマンドラインでpytestに引数を渡す方法

コードがあり、ターミナルから名前のような引数を渡す必要があります。ここに私のコードと引数を渡す方法があります。 「ファイルが見つかりません」という種類のエラーが表示されますが、理解できません。

ターミナルでコマンドを試しました:pytest <filename>.py -almonds名前を「アーモンド」として印刷する必要があります

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

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
25
clay

使用 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
.
9
Okken

ここで、引数を渡す方法を探してつまずきましたが、テストのパラメーター化を避けたいと思いました。上記の回答は、コマンドラインからテストをパラメーター化するという正確な問題に完全に対応していますが、コマンドライン引数を特定のテストに渡す別の方法を提供したいと思います。以下のメソッドはフィクスチャを使用し、フィクスチャが指定されているが引数が指定されていない場合、テストをスキップします。

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

公式ドキュメント によると、マークデコレータは次のようになります。

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

実行

_python -m pytest <filename>.py
_
  • 注1:関数名は_test__で始まる必要があります
  • 注2:pytestはstdout (print)をリダイレクトするため、stdoutを直接実行すると画面に結果を表示できません。また、テストケースで関数に結果を出力する必要はありません。
  • 注3:pytestはpythonによって実行されるモジュールであり、sys.argvを直接取得することはできません

構成可能な引数の外で本当に取得したい場合は、スクリプト内に実装する必要があります。 (たとえば、ファイルのコンテンツをロードする)

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

コマンドラインオプションに応じて、テスト関数に異なる値を渡します
コマンドラインオプションに依存するテストを作成するとします。これを実現する基本的なパターンを次に示します。

# 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
1
Mohamed.Abdo