模拟pytest

时间:2017-04-01 22:32:27

标签: python pytest

我正在编写一个pytest插件,该插件应该测试在一组特定环境中工作的软件。

我写的软件是在一个更大的框架内运行的,这使得某些Python模块只有在框架内运行我的Python软件时才可用。

为了测试我的软件,我需要" mock"或伪造整个模块(实际上,相当多)。我需要以某种类似的方式实现其功能,但我的问题是如何使用py.test插件将这个伪造的Python模块用于我的软件代码?

例如,假设我的一个源文件中包含以下代码:

import fwlib

def fw_sum(a, b):
    return fwlib.sum(a, b)

但是,fwlib模块只能由我运行我的软件的框架提供,我无法在其中进行测试。

如何在pytest插件中确保已在fwlib中定义了名为sys.modules的模块?当然,我需要自己实施fwlib.sum。我正在寻找有关如何做到这一点的建议。

1 个答案:

答案 0 :(得分:3)

pytest为这个用例提供了一个工具:monkeypatch.syspath_prepend

您可以在sys.path导入位置列表前添加路径。写一个假的fwlib.py并将其包含在您的测试中,并根据需要附加该目录。与其他测试模块一样,它不需要包含在发行版中。

在自己玩这个之后,我实际上无法弄清楚如何从库代码中正确地模拟模块级别的导入(如果有人读取它确实找到了正确的目录结构以使其正常工作,请发布一个回答!)。

但是,我可以提供一个有效的不同解决方案:您可以从conftest.pywhich gets imported first中注入名称。后续import语句将仅重用sys.modules中已存在的对象。

包结构:

$ tree .
.
├── conftest.py
├── lib
│   └── my_lib.py
└── tests
    └── test_my_lib.py

2 directories, 3 files

文件内容:

# conftest.py
import sys

def fwlib_sum(a, b):
    return a + b

module = type(sys)('fwlib')
module.sum = fwlib_sum
sys.modules['fwlib'] = module

库文件:

# lib/my_lib.py
import fwlib

def fw_sum(a, b):
    return fwlib.sum(a, b)

测试文件:

# lib/test_my_lib.py
import my_lib

def test_sum():
    assert my_lib.fw_sum(1, 2) == 3