167

我正在尝试开始在 Python 中进行单元测试,我想知道是否有人可以解释 doctest 和 unittest 的优缺点。

你会在什么条件下使用它们?

4

11 回答 11

188

两者都很有价值。我使用 doctest 和nose来代替 unittest。我将 doctest 用于测试给出一个实际用作文档的使用示例的情况。一般来说,我不会让这些测试全面,仅仅为了提供信息。我有效地反向使用 doctest:不是根据我的 doctest 测试我的代码是否正确,而是根据代码检查我的文档是否正确。

原因是我发现全面的文档测试会使您的文档过于混乱,因此您最终会得到不可用的文档字符串或不完整的测试。

对于实际测试代码,目标是彻底测试每个案例,而不是通过示例来说明是做什么的,这是一个不同的目标,我认为其他框架更好地满足这一目标。

于 2008-12-12T10:23:35.233 回答
50

我几乎完全使用 unittest。

偶尔,我会把一些东西放在一个 doctest 可用的 docstring 中。

95% 的测试用例都是单元测试。

为什么?我喜欢让文档字符串更短一些,更切中要害。有时测试用例有助于澄清文档字符串。大多数时候,应用程序的测试用例对于文档字符串来说太长了。

于 2008-12-12T01:53:38.960 回答
36

doctesting 的另一个优点是您可以确保您的代码按照文档中的说明进行操作。一段时间后,软件更改可以使您的文档和代码做不同的事情。:-)

于 2009-03-20T20:22:31.257 回答
30

我是一名生物信息学家,我编写的大部分代码都是“一次,一项任务”脚本,这些代码只会运行一次或两次并执行单个特定任务。

在这种情况下,编写大型单元测试可能有点过头了,而 doctest 是一个有用的折衷方案。它们的编写速度更快,并且由于它们通常包含在代码中,因此它们允许始终关注代码的行为方式,而无需打开另一个文件。这在编写小脚本时很有用。

此外,当您必须将脚本传递给非编程专家的研究人员时,文档测试很有用。有些人发现很难理解单元测试的结构;另一方面,文档测试是简单的使用示例,因此人们只需复制和粘贴它们即可查看如何使用它们。

所以,继续我的回答:当你必须编写小脚本,以及当你必须将它们传递给非计算机科学家的研究人员或将它们展示给他们时,文档测试很有用。

于 2012-06-02T10:53:08.813 回答
14

如果您刚开始接触单元测试的想法,我会从它开始,doctest因为它使用起来非常简单。它还自然地提供了一定程度的文档。对于使用 进行更全面的测试doctest,您可以将测试放在外部文件中,这样它就不会弄乱您的文档。

我建议unittest您是否来自使用过 JUnit 或类似软件的背景,您希望能够以与其他地方相同的方式编写单元测试。

于 2008-12-12T01:55:25.227 回答
7

我专门使用单元测试;我认为 doctest 把主模块弄得太乱了。这可能与编写彻底的测试有关。

于 2008-12-12T02:19:46.753 回答
7

两者都使用是一个有效且相当简单的选项。该doctest模块提供了DoctTestSuiteDocFileSuite方法,它们分别从模块或文件创建与单元测试兼容的测试套件。

所以我两者都使用,并且通常使用 doctest 进行简单的测试,这些测试需要很少或不需要设置(参数的简单类型)。我实际上认为一些 doctest 测试有助于记录功能,而不是减损它。

但是对于更复杂的情况,以及更全面的测试用例集,我使用 unittest,它提供了更多的控制和灵活性。

于 2008-12-12T03:25:02.330 回答
7

我不使用 doctest 作为 unittest 的替代品。尽管它们有些重叠,但两个模块的功能不同:

  • unittest用作单元测试框架,这意味着它可以帮助我快速确定任何修改对其余代码的影响。

  • doctest用作保证注释(即文档字符串)仍然与当前版本的代码相关。

我从unittest. doctest解决了过时的注释误导代码维护的更微妙的危险。

于 2012-12-05T11:18:02.680 回答
4

我几乎从不使用文档测试。我希望我的代码能够自我记录,并且文档字符串向用户提供文档。IMO 向模块添加数百行测试会使文档字符串的可读性大大降低。我还发现单元测试在需要时更容易修改。

于 2008-12-12T02:12:54.520 回答
4

Doctest有时会导致错误的结果。特别是当输出包含转义序列时。例如

def convert():
    """
    >>> convert()
    '\xe0\xa4\x95'
    """
    a = '\xe0\xa4\x95'
    return a
import doctest
doctest.testmod()

**********************************************************************
File "hindi.py", line 3, in __main__.convert
Failed example:
    convert()
Expected:
    'क'
Got:
    '\xe0\xa4\x95'
**********************************************************************
1 items had failures:
   1 of   1 in __main__.convert
***Test Failed*** 1 failures. 

也不检查输出的类型。它只是比较输出字符串。例如,它使某种类型有理,如果它是一个整数,它就像整数一样打印。然后假设你有返回理性的函数。因此,doctest 不会区分输出是有理整数还是整数。

于 2013-04-18T08:41:19.193 回答
2

我更喜欢基于发现的系统(“nose”和“py.test”,目前使用前者)。

当测试作为文档也很好时,doctest 很好,否则它们往往会使代码过于混乱。

于 2008-12-12T04:20:59.223 回答