我最近发表了关于伦敦Java社区调试的讨论。在谈话的问答部分中,有人向我询问了我测试驱动开发方法的方法。过去,我以更积极的方式看着这种做法。编写许多测试。那怎么会很糟糕?
但是随着时间的流逝,我以不同的眼光看到了它。我认为它是一个非常有限的工具,具有非常特定的用例。它不适合我构建的项目类型,并且经常阻碍它应该促进的流体过程。但是让我们回溯一秒钟。我真的很喜欢this post分开TDD中的类型和问题。但是,让我们简化一点,让我们澄清每个公关都应该具有良好的覆盖范围。这不是TDD。这只是很好的编程。
tdd不仅如此。在其中,我们需要定义约束,然后解决问题。该方法是否优于解决问题,然后验证约束是正确的吗?这是TDD的核心前提与仅编写良好的测试覆盖范围。
好
TDD是一种有趣的方法。在使用松散类型的语言时,它特别有用。在那些情况下,TDD很棒,因为它填补了严格的编译器和衬里的角色。
在其他情况下,这是有道理的。当我们构建一个具有很好定义的输入和输出的系统时。在建造课程和材料时,我会遇到很多这样的案例。在处理现实世界数据时,这有时会在我们具有处理数据并以预定义格式输出的中间件时发生。
这个想法是在中间构建具有隐藏变量的方程式。然后编码在方程式中填充。在这样的情况下,它非常方便。编码在空白中填充。
坏
测试驱动的开发 IS 双重入口簿记。相同的学科。相同的推理。同样的结果。
我认为测试有点像双重入口簿记。是的。我们应该进行测试。问题是我们应该根据测试构建代码,反之亦然吗?在这里,答案并不简单。
如果我们有一个带有测试的预先存在的系统,那么TDD在世界上都有意义。但是测试尚未构建的系统。在某些情况下,这是有道理的,但不像人们想的那样频繁。
TDD的最大主张是其设计。测试实际上是系统设计,然后我们实施该设计。问题在于我们也可以调试设计。过去,我为一家主要的日本公司工作了一个项目。该公司拥有最大,最详细的附件设计书籍之一。根据这些设计规范,公司建立了数千个测试。我们应该对系统进行大量测试。请注意,大多数人甚至是自动的。
测试有错误。有许多相互竞争的实现,但没有一个在测试中找到错误。为什么?他们都使用相同的参考实现源代码。我们是第一个跳过这一点并进行清洁室实施的团队。它使这些错误在代码中持续了,其中一些是严重的性能错误,影响了所有以前的版本。
,但真正的问题是进步缓慢。该公司无法迅速前进。 TDD支持者将很快评论说,TDD项目更容易重构,因为测试使我们保证我们不会回归。但这适用于事实后进行测试的项目。
更糟
TDD重点关注快速单元测试。进行慢速集成测试或可以在TDD系统上过夜的长期测试是不切实际的。您如何验证规模和集成到主要系统中?
在理想的世界中,一切都会像乐高积木一样单击到位。我不会生活在这样的世界中,集成测试失败了。这些是最严重的失败,最难跟踪错误。我宁愿在设备测试中失败,这就是为什么我要有它们。它们很容易修复。但是,即使有完美的覆盖范围,他们也无法正确测试互连。我们需要集成测试,他们发现最可怕的错误。
结果,TDD过度强调了对基本集成测试进行单位测试的好。是的,你应该两个。但是我必须进行集成测试。那些不像TDD的过程不那么合适。右驱动测试
我逐案的方式编写测试方式。如果我有事先进行测试是自然的情况,那么我会使用它。但是在大多数情况下,首先编写代码对我来说似乎更自然。在编写测试时,审查覆盖范围非常有帮助,这是我事后做的事情。
正如我之前提到的,我仅检查覆盖范围以进行集成测试。我喜欢单元测试并监视那里的覆盖范围,因为我也希望在那里进行良好的覆盖范围。但是对于质量,仅集成测试很重要。公关需要单位测试,如果我们在实施之前编写它们,我不在乎。我们应该判断结果。
不良自动化
当特斯拉建立自己的3型工厂时,他们进入了生产地狱。问题的根源是他们试图自动化一切。 Pareto Principle非常适用于自动化。有些事情只是对自动化的抵抗力,使整个过程变得更糟。
真正失败的一个点是UI测试。诸如硒等的解决方案在测试网络前端取得了长足的进步。尽管如此,复杂性还是很大的,测试非常脆弱。我们最终很难维持测试。更糟糕的是,我们发现UI更难重构,因为我们不想重写测试。
我们可能可以跨越测试功能的80%,但是自动化回报率降低了。在这些环境中,TDD是有问题的。功能很容易,但是构建测试变得站不住脚。
最后
我不反对TDD,但我不建议它,实际上我不使用它。当从测试开始时,我可能会这样做,但这并不是真正的TDD。我根据结果判断代码。 TDD可以提供出色的结果,但通常会过分强调单位测试。从长远来看,集成测试对于质量更为重要。
自动化很棒。直到停止。在某种程度上,自动测试毫无意义。这将为我们节省很多时间和精力来接受这一点,并将我们的精力集中在富有成效的方向上。
这是从我作为Java开发人员的偏见中,喜欢类型安全,严格的语言。 JavaScript和Python等语言由于其灵活性而受益于大量测试。因此,TDD在这些环境中更有意义。
总而言之,测试很好。 TDD并没有进行更好的测试。如果对您有用,这是一种有趣的方法。在某些情况下,这很大。但是,TDD至关重要,甚至将显着改善所产生的代码的想法是没有意义的。