【问题标题】:Passing command line arguments in python by pytest通过pytest在python中传递命令行参数
【发布时间】:2017-08-04 07:47:20
【问题描述】:

我可以在运行时传递命令行参数

python <filename>.py arg1

但是,当我尝试传递命令行参数以运行 pytest 时,它会失败并给出如下错误。能否请教。

pytest <filename>.py arg1
ERROR: file not found: arg1

编辑:

例如,假设我已经传递了一个参数并正在通过 sys.argv 读取它,我正在考虑以这种方式使用它:

import sys
arg = sys.argv[3]
def f():
    return 3

def test_function():
    assert f() == arg

【问题讨论】:

  • 你需要它做什么?
  • 我想传递数据并将其存储到脚本中的变量中。可能吗..?谢谢。
  • 你不应该像这样参数化你的测试。测试应尽可能独立。如果您必须为您的应用程序测试argvs,请模拟它们。
  • 感谢同意。我只是想尝试是否可以以这种方式传递参数。请让我知道是否有可能。

标签: python


【解决方案1】:

您的pytest &lt;filename&gt;.py arg1 命令试图在&lt;filename&gt;.pyarg1 两个模块上调用pytest,但是没有模块arg1。

如果您想在运行 pytest 之前传递一些参数,请在提取变量后从 python 脚本运行 pytest。

正如其他人建议的那样,尽管您可能希望以其他方式参数化您的测试,请尝试:Parameterized pytest

# run.py
import pytest
import sys

def main():
    # extract your arg here
    print('Extracted arg is ==> %s' % sys.argv[2])
    pytest.main([sys.argv[1]])

if __name__ == '__main__':
    main()

使用python run.py filename.py arg1调用它

【讨论】:

  • 不幸的是,我遇到了与以前相同的错误 - 错误:找不到文件
  • 你能告诉我**在这里提取你的 arg 是什么意思
  • @anukb 我已经更新了代码,但我不确定你会传​​递多少个参数。您可以查看stackoverflow.com/questions/4117530/sys-argv1-meaning-in-script 了解有关 sys arg 的更多详细信息
【解决方案2】:

这是我刚刚通过阅读parameterized pytest docs 并进行了一段时间的黑客攻击...我不知道它的整体稳定性或良好程度,因为我刚刚开始工作。 然而,我确实检查了 HTML 覆盖率生成是否适用于这种方法。

# this is just so we can pass --server and --port from the pytest command-line
def pytest_addoption(parser):
    ''' attaches optional cmd-line args to the pytest machinery '''
    parser.addoption("--server", action="append", default=[], help="real server hostname/IP")
    parser.addoption("--port", action="append", default=[], help="real server port number")
def pytest_generate_tests(metafunc):
    ''' just to attach the cmd-line args to a test-class that needs them '''
    server_from_cmd_line = metafunc.config.getoption("server")
    port_from_cmd_line = metafunc.config.getoption("port")
    print('command line passed for --server ({})'.format(server_from_cmd_line))
    print('command line passed for --port ({})'.format(port_from_cmd_line))
    # check if this function is in a test-class that needs the cmd-line args
    if server_from_cmd_line and port_from_cmd_line and hasattr(metafunc.cls, 'real_server'):
        # now set the cmd-line args to the test class
        metafunc.cls.real_server = server_from_cmd_line[0]
        metafunc.cls.real_port = int(port_from_cmd_line[0])


class TestServerCode(object):
    ''' test-class that might benefit from optional cmd-line args '''
    real_server=None
    real_port = None

    def test_valid_string(self):
        assert self.real_server!=None
        assert self.real_port!=None

    def test_other(self):
        from mypackage import my_server_code
        if self.real_server !=  None:
            assert "couldn\'t find host" not in my_server_code.version(self.real_server, self.real_port)
  • 然后运行(例如使用 HTML 覆盖):

    • pytest tests\test_junk.py --server="abc" --port=123 --cov-report html --cov=mypackage

【讨论】:

  • 好提示,谢谢。我使用这种方法允许在运行测试时在命令行上传递用户名/密码。以前,我必须在源代码中硬编码凭据,我真的很讨厌。一个负面影响是执行测试时将用户名/密码打印到终端。我不喜欢这样,但考虑到控制台在使用其他选项(用户名、密码)执行 Pytest 时已经具有可见的凭据,这是可以接受的。
  • 添加一个虚拟帐户?那么密码出现就不是什么大问题了
猜你喜欢
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多