【问题标题】:In Django, when should I use doctests instead of unit testing?在 Django 中,我什么时候应该使用 doctests 而不是单元测试?
【发布时间】:2011-05-14 04:14:11
【问题描述】:

来自Django docs

...数据库在 doctest 之间不会刷新,因此如果您的 doctest 需要某种状态,您应该考虑刷新数据库或加载夹具。

坦率地说,我目前 90% 的测试都是在 doctests 中完成的。我的一位同事认为这很奇怪。老实说,我做的测试很少,所以我不会假装自己是那个领域的大师。

在决定如何测试时,是否有人有他们使用的经验法则?

非 SO 答案

我的一位同事建议通过单元测试将模型功能和约束作为文档测试和视图进行测试。根据经验,这听起来如何?

【问题讨论】:

    标签: python django unit-testing testing doctest


    【解决方案1】:

    随着项目的发展,您会发现单元测试更适合测试您的代码。

    Django 项目本身正在将所有 doctest 转换为 unittest(我们将在 1.3 版本中完成)。我们这样做的原因是在此转换之前,测试套件中的执行顺序有时会导致难以重现的错误。有时一些代码会意外地依赖于以前运行的 doctest 代码。此外,切换到单元测试加快了整体测试时间,因为我们可以更明智地了解如何以及何时清除数据库。

    单元测试的另一个优势是它们更容易维护。因为整个测试用例是自包含的,您要么编写另一个测试用例,要么修改小的、有针对性的测试功能以适应。

    Doctests 倾向于通过进化来工作 - 你得到一个你的小部件实例,添加绿色毛发,确保毛发是绿色的,添加 4 条腿,确保你有 4 条腿和绿色毛发,添加拇指,确保你有一个拇指、4 条腿和绿色毛皮等……这意味着如果您想在绿色毛皮阶段之后立即添加测试,则必须为随后的每个其他测试用例修改预期结果。

    您不想进行所有这些重写,因此您在最后添加了新测试。然后您添加另一个,然后过了一段时间,您的测试变得如此混乱,您甚至无法确定是否测试了特定功能!使用单元测试,因为每个测试都体现了一个特定的、具体的和有限的想法,所以更容易在逻辑上重新排序测试,并添加一个不依赖于所有先前测试的新测试。此外,如果您更改add_green_fur() 的工作方式,您不必修改数十个测试用例结果。

    另一个优点是单元测试(如果写得好)可以准确地告诉您代码失败的地方。 Failed: MyWidget.tests.test_green_fur() 比“widget test failed at line 384”更容易调试,这通常与实际的故障点相差几十到几百行。

    一般来说,单元测试是更好的测试方法。

    编辑:

    作为对你同事的想法的回应,我恭敬地建议他没有参与过一个包含许多 doctest 的大型项目。模型中的文档测试与视图中的一样糟糕。他们有完全相同的问题(尽管如果有的话,模型中的文档测试更糟糕,因为flush 非常昂贵,并且对于彻底的文档测试是绝对必要的)。 不要低估运行测试所花费的时间成本。

    另外,除非您有充分的理由,否则不要混合您的测试类型。如果你这样做了,你很快就会发现自己在重复测试,或者假设一个函数在你没有看到的任何测试套件中进行了测试。

    Doctests 通常被吹捧为“提供文档”以说明您的代码应该如何工作。这很好,但它不能替代使用清晰易读的内联 cmets 编写可读代码。如果您需要更多文档,请单独写出来!

    你不能编写好的测试同时作为好的文档。

    【讨论】:

    • 很好的洞察力。当您说“此外,切换到 doctests 加快了整体测试时间......”您的意思是切换到 unittests 吗?还是我错过了什么?
    • +1 用于单元测试。对此有一个绝妙的答案:stackoverflow.com/questions/361675/python-doctest-vs-unittest/…
    • @Nimmy 是的,切换到单元测试使测试套件运行得更快,主要是因为我们消除了一堆完整的数据库刷新。
    • 再次感谢 McMillan 先生。您的回答非常有用!
    【解决方案2】:

    Doctests 非常适合确保您的文档是最新的,但我不会真正使用它们来测试代码。当您更改代码时,您的文档很容易过时。

    简而言之,使用单元测试来测试代码,使用文档测试来测试文档。

    【讨论】:

    • 特别是对于不庞大的库,我发现 docstrings 中的 doctests 是理想的。它只是流动得很好,很好地达到了目的。此外,当涉及到外部文档时,如果您使用的是 Sphinx,您可以让它运行它找到的任何文档测试。您可以有一个专门用于测试的部分 - 也可以在测试时记录测试。
    猜你喜欢
    • 1970-01-01
    • 2016-08-09
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2010-11-07
    相关资源
    最近更新 更多