我们有一个python模块,调用者可以使用它来在Mac OS X上运行一些实用程序命令。命令的路径及其用法因操作系统版本而异,我们的模块旨在将其隐藏起来。我们在导入模块时确定一次操作系统的版本,就像这样(import platform
from distutils.version import StrictVersion
print('Importing helper module...')
os_version, _, _ = platform.mac_ver()
if StrictVersion(os_version) < StrictVersion('10.10'):
utility1 = 'utility 1 for 10.9 and below'
else:
utility1 = 'utility 1 for 10.10 and above'
def run_utility1():
return 'Running ' + utility1
def run_utility2():
# ...
pass
# ... more cool functions ...
,简化以证明这一点):
patch
现在我们要为此模块添加测试。具体来说,我们要确保为所有版本的OS X运行正确的实用程序。我想到的方法是在不同的测试中platform.mac_ver()
assert
返回不同的操作系统版本,和import mock
import unittest
class HelperTests(unittest.TestCase):
def test_10_9_utility_is_correct(self):
with mock.patch('platform.mac_ver', return_value=('10.9', 'foo', 'foo')):
import helper
result = helper.run_utility1()
print(result)
assert result == 'Running utility 1 for 10.9 and below'
def test_10_10_utility_is_correct(self):
with mock.patch('platform.mac_ver', return_value=('10.10', 'foo', 'foo')):
import helper
result = helper.run_utility1()
print(result)
assert result == 'Running utility 1 for 10.10 and above'
if __name__ == '__main__':
unittest.main()
我们正在运行正确的实用程序。像这样:
Testing started at 12:16 PM ...
Importing helper module...
Running utility 1 for 10.10 and above
Running utility 1 for 10.10 and above
Process finished with exit code 0
Failure
Traceback (most recent call last):
File "helper_test.py", line 13, in test_10_9_utility_is_correct
assert result == 'Running utility 1 for 10.9 and below'
AssertionError
但结果是:
test_10_10_utility_is_correct
似乎mac_ver()
首先运行(这是由于测试工具中方法的字母排序吗?),修补10.10
以返回helper
然后导入{{1} }。当test_10_9_utility_is_correct
运行时helper
没有再次导入,因此它会失败,因为它认为它在10.10上。
据我所知,python没有两次导入模块,而且非常棒。但这是否意味着我们不能在测试中的模块级代码中运行分支,因为它只会运行一次?如果有办法,怎么做?
我考虑过在函数中包装模块级操作系统版本检查代码。这将使模拟变得容易,但是所有其他函数必须首先调用它,这似乎是不必要的,因为操作系统版本不可能在调用之间改变。我还考虑过将每个测试方法移动到自己的测试模块中,这会导致helper
多次导入,但这看起来非常笨重。是否有另一种方法来行使helper.py
中给出的两个分支?
答案 0 :(得分:0)
如何将初始化代码放入函数中?
你必须像这样声明你的全局变量:
import platform
from distutils.version import StrictVersion
utility1 = None
def init_module():
global utility1 # declare it global to modify it
print('Importing helper module...')
os_version, _, _ = platform.mac_ver()
if StrictVersion(os_version) < StrictVersion('10.10'):
utility1 = 'utility 1 for 10.9 and below'
else:
utility1 = 'utility 1 for 10.10 and above'
init_module() #Call the init function when importing the module
def run_utility1():
return 'Running ' + utility1
然后在每个新测试中,您可以调用init函数:
import mock
import unittest
import helper
class HelperTests(unittest.TestCase):
def test_10_9_utility_is_correct(self):
with mock.patch('platform.mac_ver', return_value=('10.9', 'foo', 'foo')):
helper.init_module()
result = helper.run_utility1()
print(result)
assert result == 'Running utility 1 for 10.9 and below'
def test_10_10_utility_is_correct(self):
with mock.patch('platform.mac_ver', return_value=('10.10', 'foo', 'foo')):
helper.init_module()
result = helper.run_utility1()
print(result)
assert result == 'Running utility 1 for 10.10 and above'
if __name__ == '__main__':
unittest.main()