我有一个 python 模块/脚本可以执行其中的一些操作
- 在脚本内的不同嵌套级别,我接受命令行输入,验证它们,应用合理的默认值
- 我还会检查一些目录是否存在
以上只是两个例子。我试图找出测试这个的最佳“策略”是什么。我所做的是,我在我的模块中围绕 raw_input
和 os.path.exists
构造了包装函数,然后在我的测试中我覆盖了这两个函数以从中获取输入我的数组列表或执行一些模拟 行为。这种方法有以下缺点
- 包装函数只是为了测试而存在,这会污染代码
- 我必须记住每次都在代码中使用包装函数,而不仅仅是调用
os.path.exists
或raw_input
有什么绝妙的建议吗?
最佳答案
简短的回答是 monkey patch这些系统调用。
How to display the redirected stdin in Python? 的答案中有一些很好的例子
这是 raw_input()
的一个简单示例,它使用 lambda
丢弃提示并返回我们想要的内容。
被测系统
$ cat ./name_getter.py
#!/usr/bin/env python
class NameGetter(object):
def get_name(self):
self.name = raw_input('What is your name? ')
def greet(self):
print 'Hello, ', self.name, '!'
def run(self):
self.get_name()
self.greet()
if __name__ == '__main__':
ng = NameGetter()
ng.run()
$ echo Derek | ./name_getter.py
What is your name? Hello, Derek !
测试用例:
$ cat ./t_name_getter.py
#!/usr/bin/env python
import unittest
import name_getter
class TestNameGetter(unittest.TestCase):
def test_get_alice(self):
name_getter.raw_input = lambda _: 'Alice'
ng = name_getter.NameGetter()
ng.get_name()
self.assertEquals(ng.name, 'Alice')
def test_get_bob(self):
name_getter.raw_input = lambda _: 'Bob'
ng = name_getter.NameGetter()
ng.get_name()
self.assertEquals(ng.name, 'Bob')
if __name__ == '__main__':
unittest.main()
$ ./t_name_getter.py -v
test_get_alice (__main__.TestNameGetter) ... ok
test_get_bob (__main__.TestNameGetter) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
关于调用操作系统/模块级 python 函数的 Python 单元测试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14956825/