我将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参数列表中的选项)。
也许使用钩子?还是从包装程序注入或初始化的插件?
答案 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(...)
进行设置。>