来自Django 文档:
...数据库不会在 doctests 之间刷新,因此如果您的 doctest 需要某种状态,您应该考虑刷新数据库或加载夹具。
坦率地说,我 90% 的测试目前都是在 doctests 中完成的。我的一位同事认为这很奇怪。老实说,我做的测试很少,所以我不会假装自己是那个领域的大师。
在决定如何测试时,是否有人有他们使用的经验法则?
非 SO 答案
我的一位同事建议通过单元测试将模型功能和约束作为文档测试和视图进行测试。根据经验法则,这听起来如何?
随着项目的增长,您会发现单元测试更适合测试您的代码。
Django 项目本身正在将所有 doctest 转换为 unittest(我们将在 1.3 版本中完成)。我们这样做的原因是在此转换之前,测试套件中的执行顺序有时会导致难以重现的错误。有时一些代码会意外地依赖于以前运行的 doctest 代码。此外,切换到单元测试加快了整体测试时间,因为我们可以更明智地了解如何以及何时清除数据库。
单元测试的另一个优点是它们更容易维护。因为整个测试用例是自包含的,您要么编写另一个测试用例,要么修改小型的、有针对性的测试功能以适应。
Doctests 倾向于通过进化来工作 - 你得到一个你的小部件实例,添加绿色毛发,确保毛发是绿色的,添加 4 条腿,确保你有 4 条腿和绿色毛发,添加拇指,确保你有拇指, 4 条腿, and green fur, etc... 这意味着如果你想在 green fur 阶段之后添加一个测试,你必须修改每个其他测试用例的预期结果。
你不想做所有这些重写,所以你在最后添加你的新测试。然后你添加另一个,然后过了一段时间你的测试变得如此混乱,你甚至无法弄清楚是否测试了特定功能!使用单元测试,因为每个测试都体现了一个特定的、具体的和有限的想法,所以更容易在逻辑上重新排序测试,并添加一个不依赖于所有先前测试的新测试。此外,如果您改变工作方式add_green_fur()
,您不必修改数十个测试用例结果。
另一个优点是单元测试(如果写得好)可以准确地告诉您代码失败的地方。Failed: MyWidget.tests.test_green_fur()
比“widget test failed at line 384”更容易调试,这通常离实际的故障点有几十到几百行。
一般来说,单元测试是更好的测试方法。
编辑:
作为对你同事的想法的回应,我恭敬地建议他没有参与过一个有很多 doctest 的大型项目。模型中的文档测试与视图中的一样糟糕。它们有完全相同的问题(尽管如果有的话,模型中的 doctests 更糟糕,因为flush
它非常昂贵并且对于彻底的 doctesting 绝对必要)。不要低估运行测试所花费的时间成本。
此外,除非您有充分的理由这样做,否则不要混合您的测试类型。如果你这样做了,你很快就会发现自己加倍了测试,或者假设一个函数在你没有看到的任何测试套件中进行了测试。
Doctests 通常被吹捧为您的代码应该如何工作的“提供文档”。这很好,但它不能替代编写具有良好易读内联注释的可读代码。如果您需要更多文档,请单独写出来!
你不能编写好的测试也可以作为好的文档。
Doctests 非常适合确保您的文档是最新的,但我不会真正使用它们来测试代码。当您更改代码时,您的文档很容易过时。
简而言之,使用单元测试来测试代码和文档测试来测试文档。