什么是模拟os.system单元测试(PyTest)
问题描述:
我有一个Python脚本,可以执行多个os.system
调用。将其作为一系列字符串进行声明将会很容易(并且相对优雅)。什么是模拟os.system单元测试(PyTest)
不容易的是拦截(并阻止)实际的呼叫。在有问题的剧本,我可能会在SUT(*),像这样抽象的使用os.system:
os_system = None
def main():
return do_the_thing(os.system)
def do_the_thing(os_sys):
global os_system
os_system = os_sys
# all other function should use os_system instead of os.system
我的测试调用my_script.do_the_thing()
,而不是当然的my_script.main()
(留下的未经测试的代码一个很小的量)。
备用选项:我可以离开SUT不变,并在SUT调用main()
前的测试方法取代os.system
全球。
这给我留下了新的问题,因为这是一个全球性的持久变化。很好,所以我会在相同的测试方法中使用try/finally
,并在离开测试方法之前替换原件。无论测试方法通过还是失败,这都会起作用。
是否有这样做的PyTest的安全和优雅安装/拆卸中心的方式有关系吗?
其他并发症:我想为stdout和stderr做同样的事情。是的,它确实是我正在测试的main()
脚本。
- SUT ==被测系统
答
Python的3(> = 3.3)标准库具有正式文件在great tutorial about Mock。对于Python 2,您可以在PyPi上使用backported库:Mock。
以下是一个示例用法。假设你希望将电话嘲笑到os.system
在这个函数:
import os
def my_function(src_dir):
os.system('ls ' + src_dir)
要做到这一点,你可以使用unittest.mock.patch
装饰,就像这样:
import unittest.mock
@unittest.mock.patch('os.system')
def test_my_function(os_system):
# type: (unittest.mock.Mock) -> None
my_function("/path/to/dir")
os_system.assert_called_once_with('ls /path/to/dir')
过程中,该测试功能将修补os.system
通话它的执行。在最后恢复os.system
。
然后,有几个“断言”方法来检查调用,参数和结果。您还可以检查某些情况下是否发生异常。
太好了。对于PyTest和Python2,它只是@ mock.patch('os.system'),我可以很好地确认作品。 –