繁体   English   中英

pytest - 测试外的命令行参数 function

[英]pytest - command line argument outside test function

如何将命令行选项作为变量传递给我的 pytest 非测试文件,例如数据库名称。

当我尝试:

import sys
import getopt


"""argv = sys.argv[1:]

opts, args = getopt.getopt(argv, "e:")

for opt, arg in opts:
    if opt in ['-e']:
        if arg == "test1":
            base_url = "url-test1.com"
            db_name = "db_test1"
        elif arg == 'test2':
            base_url = "url-test2.com"
            db_name = "db_test2"
        elif arg == 'test3':
            base_url = "url-test3.com"
            db_name = "db_test3"
    return base_url

并运行

 python -m pytest -e test1

看起来像 pytest 无法获得 -e 标志

错误:用法: main .py [options] [file_or_dir] [file_or_dir] [...]

.py:错误:无法识别的 arguments:-e

inifile: 无

我也尝试 pytest addoption 并将变量传递给测试文件工作正常,但如何将 cmnd 行选项作为值传递给非测试文件?

def pytest_addoption(parser):
    parser.addoption("--url", action="store", default="url-test1.com")
    parser.addoption("--db", action="store", default="test1")

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

def db_name(request):
    return request.config.getoption("--db") #I want to pass this value to mysql.connector as database=db_name

编辑 1

所以我的 db_connect.py 喜欢这样

import mysql.connector
import argparse


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--db', required=True, type=str, help="Your database name")
    return parser.parse_args()


def main():
    args = parse_args()
    db = args.db
    return db


mydb = mysql.connector.connect(
    user='username',
    password='password',
    host='host',
    database=main()
)


if __name__ == '__main__':
    main()

当我尝试跑步时

py.test --db test1

我收到了这个错误

ERROR: usage: py.test [options] [file_or_dir] [file_or_dir] [...]
py.test: error: unrecognized arguments: --db
  inifile: None

但是当我跑步时

py.test

我有

usage: py.test [-h] --db DB
py.test: error: the following arguments are required: --db

参数是必需的,但是当我通过时,它无法识别。 如何处理?

欢迎!

特别是要“覆盖”变量、模块和对象,您应该模拟它们。 测试中的 Mocking 是指在创建真正的 object 时,创建与原始 object 具有相似行为的假 object 是昂贵的。 比如数据库连接。 但是,当然,它不仅限于数据库。 您可以模拟任何 object 以及sys.argv
您可以在pytest文档中更广泛地阅读有关 mocking 的信息,但这是一个简短的示例

import module_to_test


def mytest(monkeypatch):
    """
    Mocks the configuration parameters values.
    """
    monkeypatch.setattr(module_to_test.sys, 'argv', ['somescript.py', '--db'])

话虽如此,我强烈建议您不要使用getopt 这是从 bash 的世界中解析bash的不推荐使用的方法。 有一个强大的 package 称为argparse ,它完全取代了任何此类参数样板代码。

import argpase


def parse_args():
    """
    Parse arguments given in the command line. Expects just "--db"
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--db', required=True, type=str, help="Your DB name")
    return parser.parse_args()


def main():
    args = parse_args()
    db = args.db
    print(f"Wrap 10 to {db}. Engage!")


if __name__ == '__main__':
    main()

argparse 文档

编辑 1

在那个argparse上做得很好!

现在,您可以简单地模拟它。 您不再需要它解析命令行。 您想控制它返回的内容。 因此,这一次,当您使用monkeypatch模拟argparse.ArgumentParser时,您将传入您自己的“虚拟类”,它什么都不做,只会在parser.parse_args()时返回固定的 arguments。 这是 class 的示例(您可能需要对其进行调整)

from collections import namedtuple


class DummyParser:
    def add_argument(self, *_, **__):
        """
        We know what arguments we want, we don't need to implement this.
        """
        pass

    def parse_args():
        """
        Money time!
        """
        fake_return_class = namedtuple('Namespace',
                                       ['db', 'the value we want for db'])
        args = fake_return_class(db="the value we want")
        return args


fake_parser = DummyParser()
fake_args = fake_parser.parse_args()
print(fake_args.db)

一项调整可能是使其更具可重用性,并添加您自己的db等于的构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM