评估是先在蓝天/原型项目上编写单元测试还是集成测试


11

我最近注意到的是,当我执行以下类型的项目时:

  • 开始项目时
  • 处理MVP /原型
  • 添加未完全定义的功能
  • 从事较小规模的项目

作为参考,我正在研究一个Python项目,该项目目前有大约1k行代码,包括一些注释和所有空格。

我发现首先编写集成测试,处理代码,然后对API进行某种程度的加固后,实际上可以轻松地添加单元测试。可以说,我可以在我的main函数上运行的测试类型比其他任何东西都更“端到端”。

这是因为当API发生相当快速的更改时,单元测试确实很烦人,而在与以上任何或大多数条件匹配的项目上工作时,通常就是这种情况。

这种方法是否是一种好的方法,并且在针对这些类型的项目做出是否首先从单元测试或集成测试开始的决策时应考虑哪些标准?在API更加巩固之前,我是否错过了对这类项目进行单元测试的价值?


6
做最适合您的事情。不要听别人说必须以某种方式工作才能提高效率:您知道什么时候有效率,什么时候没有效率。究竟是先编写集成测试还是先编写单元测试,都没有关系。对于某些项目,一种方式可能更容易,而对于另一些项目,则另一种方式。您所描述的可能是自顶向下和自底向上设计之间的差异。两者都很有用,但是自上而下通常可以产生更好的设计。
弗兰克·希勒曼

@FrankHileman确实是我的方法。但由于我很好奇,因此我想确保自己在做正确的方法,以防万一我遗漏了某些东西。
enderland

首先关注规范:非代码部分。系统的不变性是什么?在执行此操作时,您可能会发现需要先确定低级别或高级。这取决于最关键或风险最大的算法的位置。尝试先将它们清除。那就是基本的风险管理。
弗兰克·希勒曼

1
在开发原型的情况下,完全不编写测试是可以的。原型的目的是检查工作思路。原型的实施将有助于识别预期的应用程序设计。
法比奥

这就是所谓的由外而内的开发。您可能想看看下面的书,该书正是这样做的:amazon.com/dp/0321503627
Eternal21'4

Answers:


7

在API更加巩固之前,我是否错过了对这类项目进行单元测试的价值?

不,你很好。

TDD的两个主要目标是:

  • 通过实际用法而不是内部实现来定义接口1
  • 最大化测试范围

无论哪种方式,测试覆盖率都可以很好地最大化。也就是说,无论您是先测试小型的,隔离的单元还是大型的 “集成”单元,都可以选择在实现之前编写测试。

首先,您在编写更高级别(“集成”)测试时所获得的好处是,可以确保主要根据其用法而不是根据其内部实现来定义更高级别的接口和交互。

通过一些良好的“架构”和图解,可以在很大程度上实现相同的效果。但是,那些高级测试通常可以揭示您在图表中遗漏的东西,或者您在“体系结构”工作中刚犯错的东西


如果您实际上并没有进行TDD(或类似的工作),则编写测试的顺序并不重要。这些接口在您进行测试时就已经存在,因此测试更改任何东西的可能性都大大降低了–它们用于防止特定的重大更改。

但是,如果您关心的是自上而下还是自下而上地构建实现,则第一个要点仍然在很大程度上适用。高级代码有助于定义低级接口。鉴于,如果首先编写了低级接口(或已经存在),那么高级代码将摆在他们面前……


1.即使您没有执行完整的TDD,此规则也适用。即使您只是实现之前编写1或2个测试,这些1或2个测试也可以帮助您定义或优化接口,以免为时已晚!


1

我按照您的工作方式工作。而且我不会告诉你你做不到。我会警告您可能会遇到的问题。

当每个单元测试都只是一个改造时,很难学习使其变得灵活。它们往往只不过是回归测试。由于您从未使用过它们来帮助您进行重构,因此编写编写实际上使重构更加困难的测试非常容易。这往往会失控,直到您对TDD失去全部信心。

但是,您已经在做某事。我不会告诉你停下来。我会说,值得您花些时间探索并从一开始就遵循红绿色重构周期的其他事情是值得的。确保您确实使用测试来帮助您进行重构。除非您掌握了这种工作方式,否则请谨慎地将其用于重要的事情上。这是一种非常不同的编码方式,需要习惯。半途而废不会有任何好处。

那说

我发现首先编写集成测试,处理代码,然后对API进行某种程度的加固后,实际上可以轻松地添加单元测试。可以说,我可以在我的主要功能上运行的测试类型比其他任何东西都更“端到端”。

理解单元测试不只是作用于一个类的测试。只要您正在使用的API可以在执行以下任何一项操作的情况下进行测试,就可以进行单元测试:

  • 它与数据库对话
  • 它通过网络通信
  • 它触及文件系统
  • 它不能与任何其他单元测试同时运行
  • 您必须对环境做一些特殊的事情(例如编辑配置文件)才能运行它。

Michael Feathers:一组单元测试规则

因此,如果您的端到端测试涉及多个对象,那很好。这是单元测试,而不是对象测试。

就像不需要再测试私有方法,然后通过测试使用私有方法的公共方法对它们进行测试一样,对象也不需要在其自己的测试工具下进行初始开发。只有当对象被认为独立于端对端故事使用时,才真正需要像对待它们具有自己的界面和行为那样来对待它们。如果您对此有所注意,那就是将这些对象公开。这样,您就不会做未经测试的承诺。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.