python - 在 Django 中,什么时候应该使用 doctests 而不是单元测试?

标签 python django unit-testing testing doctest

来自 Django docs :

...the database is not refreshed between doctests, so if your doctest requires a certain state you should consider flushing the database or loading a fixture.

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

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

非SO答案

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

最佳答案

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

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

单元测试的另一个优点是它们更容易维护。因为整个测试用例是独立的,您要么编写另一个测试用例,要么修改小的、有针对性的测试函数以适应。

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

您不想重写所有这些,所以您在末尾添加了新测试。然后你添加另一个,然后过了一会儿你的测试非常困惑,你甚至无法弄清楚是否测试了特定功能!使用单元测试,由于每个测试都体现了一个特定的、具体的和有限的想法,因此逻辑上重新排序测试并添加一个不依赖于所有先前测试的新测试要容易得多。此外,如果您更改方式 add_green_fur()有效,您不必修改数十个测试用例结果。

另一个优点是单元测试(如果编写得好)会准确地告诉您代码在哪里失败。 Failed: MyWidget.tests.test_green_fur()比“widget test failed at line 384”更容易调试,后者通常距离实际故障点有几十到几百行。

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

编辑:

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

此外,除非有充分的理由,否则不要混用测试类型。如果这样做,您很快就会发现自己将测试加倍,或者假设某个功能已在您碰巧没有查看的任何测试套件中进行了测试。

Doctests 通常被吹捧为“提供代码如何工作的文档”。这很好,但它不能代替编写带有清晰易读的内联注释的可读代码。如果您需要进一步的文档,请单独写出来!

您无法编写兼具良好文档功能的良好测试。

关于python - 在 Django 中,什么时候应该使用 doctests 而不是单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4251381/

相关文章:

python - Django 检查服务器是否已经运行

unit-testing - 更好的单元测试指南

python - virtualenv 的跨平台接口(interface)

ruby-on-rails - 我应该使用纯单元测试还是集成测试来测试命令模式?

unit-testing - 从 TFS-SDK 查询失败的单元测试?

python - 多部分/混合电子邮件附件未显示,但仅在 Windows 10 邮件中显示

javascript - 在 aws lambda 上使用 child_process spawn 作为 python 脚本

python - table 和汤的问题

python - 如何使用 pymongo 在 Mongodb 中进行正则表达式搜索?

python - 他们如何在 Django 项目中的 python 控制台中运行这些命令?