将配置对象传递给pytest.main()

时间:2019-07-04 15:09:03

标签: pytest

我将pytests包装在一个进行某些设置并构建参数列表以调用pytest.main的python程序中。

arg_list = [ ... ]  //build arg_list

pytest.main(args=arg_list)

我还需要将配置对象从该包装传递给pytest运行的测试。我当时正在考虑创建一个名为conf的固定装置,并将其引用为测试功能

@pytest.fixture
def conf(request):
    # Obtain configuration object

def test_mytest(conf):
    #use configuration

但是,我还没有找到一种将任意对象传递给灯具的方法(仅pytest参数列表中的选项)。

也许使用钩子?还是从包装程序注入或初始化的插件?

1 个答案:

答案 0 :(得分:0)

您可以创建一个在包装器和测试之间共享的模块,或者首先序列化该对象。

在测试之前先戳一下对象并加载它

此解决方案可使您的包装程序和测试大部分保持独立。如果要重现特定对象的测试输出,仍可以直接执行测试并从命令行传递配置对象。 它不适用于所有对象,因为不是所有对象都可以被腌制。有关更多详细信息,请参见"What can be pickled and unpickled?"。此解决方案符合固定装置的范围,因为创建固定装置时会从磁盘重新加载对象。

conftest.py中的腌制文件的路径添加命令行选项

import pickle
import pytest

def pytest_addoption(parser):
    parser.addoption("--cfg-obj", help="path to the pickled configuration object")

@pytest.fixture
def conf(request):
    path = request.config.getoption("--cfg-obj")
    with open(path, 'rb') as fp:
        return pickle.load(fp)

wrapper.py中戳对象并将其保存在临时文件中。

import pickle
import tempfile
import pytest

config_obj = {"answer": 42}

with tempfile.NamedTemporaryFile(delete=False) as fp:
    pickle.dump(config_obj, fp)
    fp.close()

    args_list = ["tests.py", "--cfg-obj", fp.name]
    pytest.main(args=args_list)

使用conf中的tests.py固定装置

def test_something(conf):
    assert conf == {'answer': 42}

在包装器和测试之间共享对象

在我看来,这种解决方案似乎不是很“干净”,因为没有包装器就无法执行测试(除非如果未设置对象,则添加回退),但是它的优点是包装器和测试访问同一对象。这将适用于任意对象。如果您修改对象的状态,这也会在测试之间引入一种可能的依赖关系,因为灯具装饰器的scope参数在这里无效(它总是加载相同的对象)。

创建一个shared.py模块,该模块由测试和包装程序导入。它为共享库提供了一个setter和getter。

_cfg_obj = None


def set_config_obj(obj):
    global _cfg_obj
    _cfg_obj = obj


def get_config_obj():
    global _cfg_obj
    return _cfg_obj

wrapper.py

中设置共享对象
import pytest

from shared import set_config_obj

set_config_obj({"answer": 42})

args_list = ["tests.py"]
pytest.main(args=args_list)

将共享对象加载到conf固定装置中

import pytest

from shared import get_config_obj

@pytest.fixture
def conf():
    return get_config_obj()

def test_something(conf):
    assert conf == {"answer": 42}

请注意,shared.py模块不必位于测试目录之外。如果您通过添加__init__.py文件并将测试对象变成一个包并在其中添加共享对象,则可以从包装器中导入tests包,并用tests.set_config_obj(...)进行设置。