Python单元测试代码,调用OS/Module级python函数

Kan*_*ath 6 python unit-testing python-2.7 python-unittest

我有一个python模块/脚本,它可以完成其中的一些操作

  1. 在脚本内的各种嵌套级别,我接受命令行输入,验证它们,应用合理的默认值
  2. 我还检查是否存在一些目录

以上只是两个例子.我试图找出测试这个的最佳"策略".我所做的是,我已经构建包装函数周围raw_inputos.path.exists我的模块中,然后在我的测试中,我重写这两个函数把输入从我的数组列表或做一些嘲笑的行为.该方法具有以下缺点

  1. 包装函数只是为了测试而存在,这会污染代码
  2. 我必须记住每次在代码中使用包装函数,而不仅仅是调用os.path.existsraw_input

有什么好的建议?

Joh*_*web 3

简短的答案是对这些系统调用进行猴子修补

在How to display the redirected stdin in Python? 的答案中有一些很好的例子。

raw_input()这是一个使用 a 的简单示例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 !
Run Code Online (Sandbox Code Playgroud)

测试用例:

$ 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
Run Code Online (Sandbox Code Playgroud)