如何通过命令行在pytest中传递参数

时间:2016-11-30 04:23:19

标签: python pytest

我有一个代码,我需要传递像终端名称这样的参数。 这是我的代码以及如何传递参数。我得到了一个"文件未找到"我不明白的那种错误。

我在终端尝试了这个命令:pytest <filename>.py -almonds 我应该把这个名字打印成&#34;杏仁&#34;

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

8 个答案:

答案 0 :(得分:23)

在你的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

答案 1 :(得分:3)

您要做的就是在pytest_addoption()中使用conftest.py,最后使用request灯具:

# conftest.py

from pytest import fixture


def pytest_addoption(parser):
    parser.addoption(
        "--name",
        action="store"
    )

@fixture()
def name(request):
    return request.config.getoption("--name")

现在您可以运行测试

def my_test(name):
    assert name == 'myName'

使用:

pytest --name myName

答案 2 :(得分:2)

根据official document,标记装饰器应如下所示。

@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)
...

答案 3 :(得分:2)

我在这里偶然发现了如何传递参数,但是我想避免参数化测试。上面的答案确实很好地解决了从命令行对测试进行参数化的确切问题,但是我想提供一种将命令行参数传递给特定测试的替代方法。以下方法使用固定装置,如果指定了固定装置但参数未指定,则跳过测试:

# 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 :(得分:2)

使用background-color: red;中的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')}")

答案 5 :(得分:1)

这是一种解决方法,但它会将参数带入测试中。根据要求,这可能就足够了。

def print_name():
    import os
    print(os.environ['FILENAME'])
    pass

然后从命令行运行测试:

FILENAME=/home/username/decoded.txt python3 setup.py test --addopts "-svk print_name"

答案 6 :(得分:0)

  

根据命令行选项将不同的值传递给测试函数
  假设我们要编写一个依赖于命令行选项的测试。这里有一个   实现此目的的基本模式:

# 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

答案 7 :(得分:-3)

如果您习惯使用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.