我正在尝试在Python中开始进行单元测试,想知道有人能否解释一下doctest和unittest的优缺点。
你会在什么条件下使用它们?
我正在尝试在Python中开始进行单元测试,想知道有人能否解释一下doctest和unittest的优缺点。
你会在什么条件下使用它们?
两者都有价值。 我同时使用doctest和nose代替unittest。我使用doctest来测试一些在作为文档时有用的用法示例。通常,我不会将这些测试做得很全面,只是为了提供有用信息。实际上,我是在反向使用doctest:不是根据我的doctest检查代码是否正确,而是根据代码来检查文档是否正确。
原因是我发现全面的doctest会让文档显得混乱不堪,因此您最终要么得到无法使用的docstrings,要么得到不完整的测试结果。
对于实际测试代码,目标是彻底测试每一个情况,而不是通过示例说明它的功能,这是一个不同的目标,我认为可以通过其他框架更好地实现。
我几乎专门使用unittest进行测试。
偶尔,我会在文档字符串中添加一些可以被doctest使用的内容。
95%的测试用例都是使用unittest编写的。
为什么这样做呢?因为我喜欢保持文档字符串尽可能简短明了。有时测试用例有助于澄清文档字符串。但大多数情况下,应用程序的测试用例太长了,不适合放在文档字符串里。
docstring
描述,哪些不适合。我其实很喜欢使用 docstring
来明确地展示如何使用接口,但是将其同时用于单元测试可能不太合适。 - user1767754使用文档测试的另一个优点是您可以确保代码实际执行了文档所描述的功能。随着时间的推移,软件更改可能会使文档和代码执行不同的功能。 :-)
我是一名生物信息学家,我编写的大部分代码都是“一次性、一项任务”脚本,即仅需运行一两次并执行单个具体任务的代码。
在这种情况下,编写大型单元测试可能会过度,而文档测试是一个有用的折衷方案。它们更快速易写,并且由于通常被合并到代码中,它们允许始终关注代码应该如何行动,而不必打开另一个文件。在编写小脚本时非常有用。
此外,当您需要将脚本传递给不擅长编程的研究人员时,文档测试也很有用。有些人发现理解单元测试的结构非常困难;另一方面,文档测试是使用的简单示例,因此人们可以只需复制和粘贴它们以查看如何使用它们。
因此,总结我的答案:当您需要编写小型脚本,并需要将其传递给不是计算机科学家的研究人员时,文档测试是很有用的。
如果你刚开始接触单元测试,我建议从使用 doctest
开始,因为它非常简单易用。它还自然地提供了一定程度的文档。而对于更全面的 doctest
测试,你可以将测试放在一个外部文件中,这样就不会混淆你的文档。
如果你以前使用过 JUnit 或类似的东西,并想要以通常的方式编写单元测试,那么我建议使用 unittest
。
我只使用unittest;我认为doctest会使主模块变得混乱。这可能与编写彻底的测试有关。
同时使用两种方法是有效而相当简单的选项。 doctest
模块提供了 DoctTestSuite
和 DocFileSuite
方法,分别从模块或文件创建一个与 unittest 兼容的测试套件。
因此,我会同时使用两者,并通常使用 doctest 进行对需要很少或无需设置(参数为简单类型)的函数进行简单测试。实际上,我认为一些 doctest 测试有助于记录函数,而不是削弱它的价值。
但对于更复杂的情况,以及更全面的测试用例集,我会使用提供更多控制和灵活性的 unittest。
我几乎从不使用doctest。我希望我的代码能够自我说明,而文档字符串则为用户提供文档。在我看来,将数百行测试代码添加到模块中会使文档字符串变得难以阅读。我还发现单元测试更容易进行修改。
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不能区分输出是有理数整数还是整数。
r""" ... """
)来解决第一个问题。 - icktoofay'\\xe0\\xa4\\x95'
。 - Cees Timmerman