自测试代码

By Martin Fowler

 

  自测试代码是我在重构中使用的名称,指的是结合软件功能编写详尽的自动化测试的实践。如果做得好,这允许您调用一个命令来执行测试——这将让您有信心这些测试能够照亮隐藏在代码中的任何错误。

  我第一次接触这个想法是在一次OOPSLA会议上,听"Beddara" Dave Thomas说到每个对象都应该能够自我测试。我突然有了输入一条命令并让我的整个软件系统进行自动测试的想法,就跟你过去在启动计算机时看到硬件内存测试的方式一样。很快,我就在自己的项目中探索了这种方法,并对它的好处感到非常满意。几年后,我和Kent Beck一起做了一些工作,发现他也做了同样的事情,但方式比我复杂得多。这是在Kent(和Erich Gamma)开发出JUnit之前不久,该工具成为自测试代码(及其姐妹:TestDrivenDevelopment)的许多思考和实践的基础。

  当您可以针对代码库运行一系列自动化测试并确信如果测试通过,您的代码没有任何实质性缺陷时,您就有了自测试代码。我认为的一种方式是,除了构建您的软件系统之外,您还可以同时构建一个能够检测系统内部任何故障的错误检测器。如果团队中的任何人不小心引入了错误,检测器就会报警。通过频繁地运行测试套件,每天至少运行几次,这样您可以在引入错误后立即检测到这些错误。因此您只需查看最近的更改,就能更容易找到出错的位置。没有能工作代码和保持其能工作的测试代码的编程过程是不完整的。我们的态度是假设任何没有测试的重要代码都会被破坏。

  自测试代码是持续集成的关键部分,事实上我可以说如果你没有自测试代码,你就没有真正在进行持续集成。作为持续集成的支柱,它也是持续交付的必要组成部分。

  自测试代码的一个明显好处是它可以大大减少引入软件产品的缺陷数量。其核心是建立起一种测试文化,让开发人员认为编写代码的同时编写测试是自然而然地。

  但自测试最大的好处还不仅仅在于避免产生错误,还在于让您更有信心去对系统进行修改。旧代码库通常是可怕的地方,开发人员害怕修改工作中的代码。即使修复错误也可能是很危险的,因为您可能引入比你修复掉的缺陷还多的缺陷。这样的情况下,不仅添加更多功能非常缓慢,而且您最终还害怕重构系统,从而增加了技术债务,并陷入了一个不断恶化的螺旋,每一个修改都会让人更加害怕更多的修改。

  有了自测试代码,就是另外一番景象了。在这里,人们有信心修复小问题来清理代码是安全的,因为如果你犯了错误(或者更确切地说“当我犯了错误时”),缺陷检测器将报警,你可以快速修复然后继续。有了这个安全网,您可以花时间保持代码的良好状态,并最终进入良性循环,您可以稳步更快地添加新功能。

  这些好处经常在TestDrivenDevelopment (TDD)中被谈论,但是将TDD和自测试代码的概念分开是很有用的。我认为TDD是一种特殊的实践,它的好处包括生成自测试代码。这是一种很好的方法,而且TDD是我非常喜欢的一种技术。但是您也可以通过在编写代码后编写测试来生成自测试代码——尽管在您完成测试(并且它们通过)之前,您不能认为您的工作已经完成。自测试代码的重点是你有测试,而不是你如何得到它们。

  实践自测试代码的团队的一项重要行为是对产品错误的反应。使用自测试代码的团队通常的反应是首先编写一个暴露错误的测试,然后才尝试修复它。通常编写这个测试可能真的是一系列逐渐缩小范围的测试,直到你到达一个触发错误的单元测试。这作为一种调试技术很有用,确保一旦修复错误,它也保持修复也很重要。通常,团队也会以此错误为灵感来寻找类似的缺失测试。正确态度应该是任何错误不仅仅是代码中的失败,它同样是测试的失败。

  这些天来,我们越来越多地看到自我测试的另一个方面,更加强调生产中的监控。持续交付允许您将新版本的软件快速部署到生产环境中。在这种情况下,团队会在生产中投入更多精力来发现错误,并通过部署新的修复版本或回滚到最后一个已知良好的版本来快速修复它们。

posted @ 2022-05-05 17:18  leehsiang  阅读(132)  评论(0编辑  收藏  举报