我有一个(python3)包具有完全不同的行为,具体取决于它init()
的编辑方式(可能不是最好的设计,但重写不是一个选项)。该模块只能init()
一次,第二次给出错误。我想使用py.test来测试这个包(两个行为)。
注意:包的性质使得这两种行为互相排斥,没有任何理由可以在单一程序中同时存在这两种行为。
我的测试目录中有多个test_xxx.py
模块。每个模块都会按照需要的方式启动包(使用fixture)。由于py.test
启动python解释器一次,因此在一次py.test运行中运行所有测试模块失败。
猴子修补程序包以允许第二个init()
不是我想要做的事情,因为有内部缓存等可能导致无法解释的行为。
答案 0 :(得分:1)
要重新加载模块,请尝试使用库reload()
imp
示例:
from imp import reload
import some_lib
#do something
reload(some_lib)
此外,在新进程中启动每个测试是可行的,但多处理代码对于调试来说是一种痛苦。
实施例
import some_test
from multiprocessing import Manager, Process
#create new return value holder, in this case a list
manager = Manager()
return_value = manager.list()
#create new process
process = Process(target=some_test.some_function, args=(arg, return_value))
#execute process
process.start()
#finish and return process
process.join()
#you can now use your return value as if it were a normal list,
#as long as it was assigned in your subprocess
答案 1 :(得分:0)
我遇到了同样的问题,并找到了三种解决方案:
答案 2 :(得分:0)
一旦我遇到类似的问题,虽然设计很糟糕。
@pytest.fixture()
def module_type1():
mod = importlib.import_module('example')
mod._init(10)
yield mod
del sys.modules['example']
@pytest.fixture()
def module_type2():
mod = importlib.import_module('example')
mod._init(20)
yield mod
del sys.modules['example']
def test1(module_type1)
pass
def test2(module_type2)
pass
示例/init.py具有类似的内容
def _init(val):
if 'sample' in globals():
logger.info(f'example already imported, val{sample}' )
else:
globals()['sample'] = val
logger.info(f'importing example with val : {val}')
输出:
importing example with val : 10
importing example with val : 20
不知道您的程序包有多复杂,但是如果它只是全局变量,那么这可能会有所帮助。
答案 3 :(得分:0)
删除所有模块导入以及导入模块的测试导入:
import sys
for key in list(sys.modules.keys()):
if key.startswith("your_package_name") or key.startswith("test"):
del sys.modules[key]
您可以通过在 conftest.py
文件中使用 @pytest.fixture
装饰器配置夹具来将其用作夹具。