使单元测试变得极为有用的一个重要因素是快速反馈。
考虑一下当您的应用程序完全被集成/系统/功能测试所覆盖时会发生什么(这已经是理想的情况了,在大多数开发商店中还远远没有实现)。这些通常由专门的测试团队来管理。
- 您对SCM存储库进行了更改,
- 某个时候(可能几天后),测试人员会获得一个新的内部版本并开始对其进行测试,
- 他们找到错误并提交错误报告,
- (在理想情况下)有人将错误报告分配给您。
这可能需要几天甚至几周的时间。到这时,您已经在从事其他任务,因此您不会早先想到代码的详细信息。而且,您通常甚至没有任何直接证据来证明错误的实际位置,因此查找和修复错误需要花费大量时间。
而在单元测试(TDD)中
- 你写一个测试,
- 您编写一些代码来满足测试要求,
- 测试仍然失败,
- 您看一下代码,通常会在几秒钟内有“糟糕”的体验(例如“糟糕,我忘记检查这种情况!”),然后
- 立即修复错误。
这一切都在几分钟之内完成。
这并不是说集成/系统测试没有用。它们只是出于不同的目的。借助编写良好的单元测试,您可以在代码进入集成阶段之前发现其中的大部分错误,在该阶段发现和修复它们的成本已经非常高。正确的是,需要集成测试来捕获单元测试难以或不可能捕获的那些类型的错误。但是,以我的经验,那是比较罕见的一种。我见过的大多数错误都是由方法内部某些简单甚至琐碎的遗漏引起的。
更不用说单元测试还会测试您的接口的可用性/安全性等,从而为您提供至关重要的反馈,以改善您的设计和API。哪种IMHO可以大大减少模块/主机系统集成错误的可能性:API越容易清洁,误解或遗漏的机会就越少。
您在自动化的单元测试,自动化的集成测试和自动化的验收测试中有什么经验,而在您的经验中,哪些产生了最高的投资回报率?为什么?
投资回报率取决于许多因素,其中最重要的因素可能是您的项目是未开发的项目还是旧项目。对于未开发的项目,我的建议(到目前为止的经验)是从一开始就进行TDD样式的单元测试。我相信这是这种情况下最具成本效益的方法。
但是,在旧项目中,建立足够的单元测试覆盖范围是一项艰巨的任务,而获得收益的过程将非常缓慢。如果可能的话,尝试通过UI进行系统/功能测试来涵盖最重要的功能更为有效。(尽管自动化测试支持工具正在逐步完善,但桌面GUI应用程序可能难以通过GUI进行自动测试...)。这样可以快速为您提供一个粗略但有效的安全网。然后,您可以开始围绕应用程序的最关键部分逐步建立单元测试。
如果您只需要在下一个项目中选择一种测试形式进行自动化,那会是什么?
这是一个理论问题,我认为毫无意义。各种测试都可以在高级软件工程师的工具箱中使用,并且所有这些测试都具有无法替代的场景。