几个月前,我去一个客户那里,他们在使用测试驱动开发上遇到了很多问题。
“你们这不是在做驱动测试开发,”我说。“为了让测试发挥效能,所有的测试必须在几秒钟内能跑完,否则的话,程序员不得不频繁的停下来等待测试。”
“可是怎样才能让它们快起来?”他问,“光连接数据库就需要30秒”
于是,我想他展示了一种叫做依赖注入的技术,它能让你使用一个伪造对象来模拟数据库。“你并不需要测试你数据库,”我说。“记住,测试应该是测试那些不受控制的东西,对于测试所依赖的东西,你应该使用模拟工具使它们处于控制之中。”
他们遇到的另外一个问题—我最近也是听到了很多次—是他们的测试程序不但没起到好的作用,反而成了一个负担。“我们三天两头的要重构程序,关联的就需要重构测试程序”,这样的话从客户那里可以经常听到。
这种问题是他们把TDD想成了QA。TDD不是QA。QA是来保证程序能正确的运行的。TDD是使用断言(assertion)来表现系统的关键特征。在QA里,我们用尽可能多的方法来测试系统中可能会出错的地方。在TDD里,我们用应尽可能少的测试来表现系统的关键特征。
我遇到的大多数开发人员都很重视代码质量,努力写出高质量的代码,程序看起来很整洁。但测试用程序也是程序,经常的我能看到测试程序就写的不是那么好。
例如,一些程序员会很认真的把产品程序里的冗余部分清理干净,但在测试程序中却留下大量的无用的代码。任何冗余都不是好事,冗余的测试也是如此,如果程序有变化,冗余的测试会花掉你额外的时间去重构。
当系统出问题时,测试程序就体现出来了它最大的价值,至少对我来说是最欣慰的时候。然而,对于系统,任何一个改动只应会让一个测试失败。换句话说,没有任何两个测试的失败原因是相同的。这说起来容易做起来难,但如果你尊重这个原则,你将会发现,当你重构代码时,重构测试程序是会容易多了。
目前就说这些问题。总之,测试也是程序,它们也要保持高质量。系统中的每个关键特征都用一个测试来表现,没有第二个测试会因为这同一个问题而失败。
你怎么看待这些问题?我很想听听你的想法和建议。不要犹豫,请在评论里分享你的观点。