4

我即将开始我的第三个中型项目,并且希望(我承认这是我一生中第一次)开始使用单元测试。不过,我不知道要使用哪种方法,unitests 还是 doctests。哪种方法最有效,或者初学者应该选择实施哪种方法?谢谢

4

1 回答 1

9

我碰巧更喜欢单元测试,但两者都是优秀且开发良好的测试方法,并且都受到 Django 的良好支持(有关详细信息,请参见此处)。简而言之,每种方法都有一些关键的优点和缺点:

单元测试的优点

  • unittests允许轻松创建更复杂的测试。如果您有一个涉及调用多个辅助函数、迭代和其他分析的测试,则文档测试可能会受到限制。unittests另一方面,它只是编写 Python 代码——你可以在 Python 中做的任何事情,你都可以在那里轻松地做。拿这段代码(我曾经写过的一个单元测试的修改版本):

    def basic_tests(self, cacheclass, outer=10, inner=100, hit_rate=None):
        c = cacheclass(lambda x: x + 1)
        for n in xrange(outer):
            for i in xrange(inner):
                self.assertEqual(c(i), i + 1)
        if hit_rate != None:
            self.assertEqual(c.hit_rate(), hit_rate)
    
    def test_single_cache(self):
        self.basic_tests(SingleCache, outer=10, inner=100, hit_rate=0)
        sc = SingleCache(lambda x: x + 1)
        for input in [0, 1, 2, 2, 2, 2, 1, 1, 0, 0]:
            self.assertEqual(sc(input), input + 1)
        self.assertEqual(sc.hit_rate(), .5)
    

    我使用 basic_tests 方法在一个类上运行一些测试,然后在 for 循环中运行一个断言。在 doctests 中有很多方法可以做到这一点,但它们需要大量的思考——doctests 最擅长检查对函数的特定调用是否返回了它们应该返回的值。(在 Django 中尤其如此,它具有出色的单元测试工具(请参阅 参考资料django.test.client)。

  • doctests 会使您的代码混乱。当我编写一个类或方法时,我将尽可能多的文档放入文档字符串中,以明确该方法的作用。但是,如果您的文档字符串超过 20 行,那么您的代码中的文档数量可能与您拥有的代码一样多。这增加了阅读和编辑它的难度(关于 Python 作为一种编程语言,我最喜欢的一点是它的紧凑性)。

文档字符串的优点

  • 您的测试与特定的类和方法相关联。这意味着如果测试失败,您会立即知道哪个类和方法失败了。您还可以使用工具来确定跨类的测试覆盖率。(当然,如果您希望测试涵盖代码的许多不同部分,这也可能是限制性的)。

  • 您的测试就在代码旁边,这意味着更容易使它们保持同步。当我对类或方法进行更改时,我经常忘记对测试用例进行相应的更改(当然,当我运行它们时,我很快就会得到有益的提醒)。在您的方法声明和代码旁边放置 doctests 使这很容易。

  • 测试作为一种文档。浏览您的代码的人可以预先包含如何调用和使用每个方法的示例。

结论:我当然更喜欢单元测试,但两者都有很好的案例。

于 2012-01-11T07:04:48.670 回答