在过去一年左右的时间里,我一直在开发我的TDD印章,以便我现在相当擅长基本要点 - 首先编写测试,模拟框架,测试尽可能小的东西,DI等。
但是我觉得还有很多事情我没有从单元测试中解脱出来。
例如,我经常发现以这种方式进行单元测试并没有真正测试我的代码应该做的整合和整体更大的图片。随着一切被嘲笑,我发现我忽略了测试中的方法是否产生了我实际需要的结果,而不仅仅是他们所说的将提供的结果。当我开始转向BDD时,我发现这个问题只会加剧,导致开发时间浪费和测试无效。
另一个问题是单元测试需要大量维护才能使它们保持有序,从而减慢重构速度。
当我第一次开始单元测试时,像大多数人一样,我发现我写的是真正的集成测试。然而,这些测试有很多好处 - 它们很多更容易阅读,并且在我的程序API上充当了不错的文档。他们也倾向于更快地捕捉现实世界的问题,而不是单位测试,我发现他花了很多时间来定位仅通过错误使用API而出现的边缘情况(例如空引用,除以0等)。
你有什么想法?您能推荐一些好的书籍,文章或实践来解决更高级的单元测试并保持生产力和效率吗?
编辑:只需稍微关注一下问题,给出答案:所以基本上你说的是尽管做了所有这些单元'测试'但我真的没有测试代码......我回答说,'但我想测试当代码!' 实际上,当我写了很多“较重”的集成测试时,我发现我的代码往往更快地达到正确状态,并且很早就发现了错误。如果没有集成测试的可维护性问题,是否有可能实现这一目标?答案 0 :(得分:8)
TDD和BDD不是意味着是衡量代码质量的工具,它们是帮助设计松散耦合,高度可维护的代码片段的工具。它有更多关于API设计的事情。它的目的是确保代码完成它所说的功能,并以改变代码的一部分不会影响其他部分的方式进行。
我希望您对BDD的愤怒感来自于您正在编写工具来简单地“消除错误”或“替换您的QA流程”,BDD和TDD都不打算这样做。测试驱动开发意味着“开发,由测试驱动”,而不是“测试,由开发驱动”。在我看来,你想要后者。
集成测试和软件质量保证是完全不同的主题,但我理解这些与TDD与它们之间存在大量混淆的原因。
测试驱动开发意味着“开发,由测试驱动”,而非“测试,由开发驱动”。在我看来,你想要后者。
更新只想分享有关此问题的博文:Repeat after me: Test Driven Development is about design, NOT testing!
答案 1 :(得分:3)
我和你似乎在同一条路上。对我来说,已成为我的单元测试圣经的书是Gerard Meszaros的xUnit Test Patterns - Refactoring Test Code。
答案 2 :(得分:2)
单元测试只是一种测试,它不是唯一的测试类型。
单元测试应该涵盖尽可能小的工作单元,模拟所有依赖项是实现这一目标的一个非常关键的过程,假设这些依赖项有自己的单元测试来覆盖它们
在你覆盖了相当数量的小单位之后,然后进行所谓的功能测试,它看起来像单元测试,但它不会模拟你在一个单元中嘲笑的所有东西测试,通常如果您的系统由不同的团队构建,功能测试只会模拟其他团队引入的依赖项,但您的团队代码不会被模拟。
在介绍功能测试之后,您将进行集成测试,当您开始使用其他团队的真实依赖项时,通常您不应该在此类测试中进行任何模拟。
鉴于所有三种类型的测试都是使用mstest或NUnit构建的,它仍然是代码测试。
答案 3 :(得分:1)
如果您真正按照从业者的描述跟踪TDD,那么每个测试应该测试相对较小的代码部分(只需几行)。根据定义,这些不是集成测试。 TDD人员会告诉您,您需要一整套单独的测试来进行集成测试。
你是对的,因为这样一套TDD测试最终会让你陷入细枝末节。根据定义,测试驱动开发是树木的创建,设计和测试,而不是森林。 TDD是通过单元测试创建需求的,但就其本质而言,它体现了微观层面的需求。
如果像TDD人员声称的那样,您需要单独的集成测试,那么您还需要要求,规范和过程来配合这些测试。当您开始进入食物链时,您的测试开始变得越来越复杂,直到您达到功能/用户界面级别,自动化测试变得几乎不可能。
答案 4 :(得分:1)
查看Bertrand Mayer的“面向对象的软件构建”。
这个概念被称为“契约驱动开发”它是一个功能级别的在线测试类型,它改变了我编程的方式。
如果您在Eiffel中使用CDD,该语言也是由Bertrand编写的,它们会在测试和调试阶段由运行时自动检查。