模拟、导入和覆盖率
我正在写一个小工具,用来给控制台添加一些好看的颜色。这里有我使用的模块的简化版:
from sys import stderr
try:
from fabulous.color import fg256
clog = lambda x: stderr.write(
str(fg256(63, u'\u26A0 ' + str(x).encode('utf-8') + '\n').as_utf8))
except ImportError:
_green = '\033[1;32m'
_default = '\033[1;m'
clog = lambda x: stderr.write(_green +
u'\u26A0 ' +
str(x).encode('utf-8') +
_default +
'\n')
我可以很容易地使用 from mycolour import clog
来写一些单元测试,根据是否有好看的颜色,合适版本的 clog
会被加载。不过,一旦 clog
这个函数被加载后,就不能再卸载它。因此,任何通过 py.test 测试代码的尝试都会失败,尤其是在测试第二条路径时。
我该如何做到让测试覆盖率达到100%呢?
这是我现在的测试脚本:
try:
import builtins
except ImportError:
import __builtin__ as builtins
import unittest
from mock import MagicMock
from mock import patch
from mock import call
class ColourFabulousTest(unittest.TestCase):
def setUp(self):
pass
@patch('mycolours.stderr')
def test_fabulous_clog(self, err):
from mycolours import clog
err.write = MagicMock()
clog('ook')
self.assertTrue(err.write.called)
self.assertEqual([call('\x1b[38;5;63m\xe2\x9a\xa0 ook\n\x1b[39m')],
err.write.call_args_list)
def tearDown(self):
pass
class ColourANSITest(unittest.TestCase):
def setUp(self):
self.realimport = builtins.__import__
def myimport(name, globals, locals, fromlist, level=0):
if name == 'fabulous.color':
raise ImportError
return self.realimport(name, globals, locals, fromlist, level)
builtins.__import__ = myimport
def test_ansi_clog(self):
from mycolours import clog
builtins.__import__ = self.realimport
with patch('mycolours.stderr') as err:
clog('ook')
self.assertTrue(err.write.called)
self.assertEqual([call(u'\x1b[1;32m\u26a0 ook\x1b[1;m\n')],
err.write.call_args_list)
def tearDown(self):
builtins.__import__ = self.realimport