- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我即将开始我的第三个中型项目并希望(我承认这是我生命中的第一次)开始使用单元测试。不过,我不知道使用哪种方法,unitests 或 doctests。哪种方法最有效,或者初学者应该选择哪种方法实现?谢谢
最佳答案
我碰巧更喜欢单元测试,但它们都是优秀且开发完善的测试方法,并且都得到 Django 的良好支持(有关详细信息,请参见 here)。简而言之,每种都有一些关键的优点和缺点:
单元测试的优点
unittests
允许轻松创建更复杂的测试。如果您的测试涉及调用多个辅助函数、迭代和其他分析,doctests 可以感到局限。另一方面,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 作为一种编程语言的地方之一就是它的紧凑性)。
文档字符串的优点
您的测试与特定的类和方法相关联。这意味着如果测试失败,您会立即知道是哪个类和方法失败了。您还可以使用工具来确定您的测试在您的类(class)中的覆盖率。 (当然,如果您希望测试覆盖代码的许多不同部分,这也可能是有限的)。
您的测试紧挨着代码,这意味着它们更容易保持同步。当我对类或方法进行更改时,我常常忘记进行相应的更改到测试用例(当然,当我运行它们时,我很快就会得到有用的提醒)。将 doctests 放在方法声明和代码旁边会使这很容易。
测试作为一种文档。查看您的代码的人可以预先包含如何调用和使用每种方法的示例。
结论:我当然更喜欢单元测试,但两者都有很好的理由。
关于python - Django - Unitest 还是 Doctest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8815179/
我正在使用 doctest ,并且喜欢我可以从定义它们的地方测试非导出函数的事实: module Foo (frobnicate) where -- | -- >>> randomInt = 42 -
我有一个简单的 function with a doctest ,当使用 Sphinx 的 make doctest 运行时,出现以下错误: File "scheemey.rst", line ?,
文档似乎不太清楚如何解决以下问题...... def test(): """ >>> import doctest >>> doctest.ELLIPSIS_MARKER =
我通常使用 code auto-formatter Black ,它训练我使用双引号。使用双引号已成为我的“肌肉内存”。 许多类的默认 repr 使用单引号从 Python 交互式输出中打印出来。我知
我需要对一个必须用装饰器包装的方法进行文档测试,该装饰器不将 @functools.wraps 或 functools.update_wrapper 应用于被包装的方法.在这种情况下,doctest
我很困惑为什么 doctest.testmod() 以奇怪的顺序调用测试函数 from doctest import testmod def test_forwrite(): '''
import doctest def create_grid(size): grid = [] for i in range(size): row = ['0']*size
这可能是一个愚蠢的问题。 我正在尝试使用 python doctest,并且尝试运行 this示例 结尾为 if __name__ == "__main__": import doctest
我正在创建一个程序宏,它从一些配置文件自动生成一个库(这是一个寄存器布局,但这对问题并不重要)。 我希望库自动生成伴随自动库的文档,并包含应与 cargo test 一起运行的文档测试。现在,我已经实
这个问题在这里已经有了答案: How do you handle the "could not parse code block as Rust code" rustdoc warning? (1
我正在为一个模块编写文档,该模块具有一些由 Cargo 功能标志控制的选项。我想始终显示此文档,以便 crate 的消费者知道它可用,但我只需要在启用该功能时运行该示例。 库.rs //! This
我的函数从文件中读取,需要以独立于绝对路径的方式编写 doctest。编写 doctest 的最佳方法是什么?编写临时文件的成本很高,而且不是万无一失的。 最佳答案 您可以有一个采用路径的参数,用下划
如果我需要在 doctest 中做一些事情怎么办: ''' >>> for i in range(5): print i ''' 我明白了 for i in range(5):
我正在尝试通过 iex 使用 doctest 测试 HashSet。如果我运行下面的行,它会给出相同的结果,但是 #HashSet}无法在语法中表示。我想不出一种正确表示它的方法,也找不到任何例子。谢
我已经进行了搜索,但找不到我想要的东西。 我的代码如下: import datetime import doctest import os def parseOptions(): import
我有一个函数可以使用 random 模块将用户输入变量与随机生成的数字进行比较。我想写一个 doctest,它将要求忽略或覆盖随机生成的数字。 在我无知的情况下,我试图给随机变量赋值,但仍然生成了一个
测试这样的代码的最佳方法是什么(下面的代码显然失败了,因为每次都在不同的 block 中创建对象): def get_session(db_name, verbose, test): """Retur
我已经编写了一个用于测试的assert_raised 上下文管理器,它检查是否按预期引发异常,如果没有引发AssertionError。我还写了一个 doctest 来测试这个,但是 doctest
我有一个 doctest,我在其中测试 float 转换: >>> float('fish') 在 Python >> float('fish') ValueError:... 你可以看到 Alex
假设我有以下代码: def foo(s): """A dummy function foo. For example: >>> a = '''This is a test string lin
我是一名优秀的程序员,十分优秀!