Python unittest:在不同模块中具有重复代码的外部函数

时间:2013-10-17 14:30:35

标签: python unit-testing

假设我有一个用python编写的Web服务ServA,我想编写一些单元测试。

ServA会执行多项操作(使用不同的视图),但所有视图都会生成类似的请求日志。

这些测试应该在不同的情况下检查ServA的日志,因此这些单元测试有很多重复的代码(日志的结构总是相同的)。

我的想法是编写一个通用函数来避免重复代码,我发现this other question解决了在unittest类中创建泛型方法的问题。

但是现在如果我有另一个Web服务ServB和另一组测试,我需要做同样的事情呢?

有没有办法重用泛型函数?

我是否应该使用检查日志的方法创建一个测试类,如下所示:

class MyMetaTestClass(unittest.TestCase):
    def check_logs(self, log_list, **kwargs):
       #several self.assertEqual

然后ServA和ServB的测试继承这个类:

class TestServA(MyMetaTestClass):
    def test_log1(self):
       logs = extract_the_logs()
       self.check_logs(logs, log_1=1, log2='foo')

还有另一种(更好的)方式吗?

2 个答案:

答案 0 :(得分:5)

你可以像你一样从公共基类继承,但是基类本身不一定是TestCase子类 - 你可以把它变成一个mixin类:

# testutils.py
class LogCheckerMixin(object):
    """ this class adds log checking abilities to a TestCase.
    """  
    def check_logs(self, logs, **kw):
       self.assertWhatever(something)


# myserver/tests.py
import unittest
from testutils import LogCheckerMixin

class MyServerTest(unittest.TestCase, LogCheckerMixin):
    def test_log1(self):
        logs = extract_the_logs()
        self.check_logs(logs, log_1=1, log2='foo')

或者你可以把它变成一个普通的函数并从你的测试中调用它:

# testutils.py
def check_logs(testcase, logs, **kw):
    testcase.assertWhatever(something)


# myserver/tests.py
import unittest
from testutils import check_logs

class MyServerTest(unittest.TestCase):
    def test_log1(self):
        logs = extract_the_logs()
        check_logs(self, logs, log_1=1, log2='foo')

答案 1 :(得分:0)

它基于意见,但我最常见的是一组独立的辅助类,可以被任何测试套件使用。

我通常创建infrastructure文件夹/命名空间/模块/包(在测试项目中)不要混淆仅涉及域方面与技术问题的测试。在这种情况下,你可以这样:

logHelper.py

def assert_something_about_logs(logs, something):
    # utility code
    # do an assertion

def assert_something_else(logs):
    # utility code
    # do an assertion

通过这种方式,您的单元测试可以很好地阅读,例如assert_that_logs_contain(errorMessage="Something went wrong"),并隐藏所有技术细节,以免模糊测试。