原文出处:https://www.agileconnection.com/article/3-keys-mastering-test-driven-development
在过去的十年中,我有幸教授成千上万的专业软件开发人员如何通过测试驱动开发(TDD)实现有效性。根据这些经验,我了解到学习测试驱动开发有三个关键因素:了解它的真正含义,使代码可靠地测试,以及获得实践经验。让我们看一下这些因素,看看在项目中有效使用TDD需要什么。
1.了解TDD是什么
对测试驱动开发有效的第一个关键因素是了解它的真正含义。我发现对于如何正确地进行TDD存在很多误解,并且TDD是一种如果你做错了需要付出相当高的代价的实践。
对于TDD而言,这篇短文可能不会解释太多,但我注意到的一个最令人难以接受的事情是他们认为TDD是一种测试或质量保证形式。我相信这是对待TDD的一种错误的心态。
质量保证的思维方式是会考虑可能出现的问题并找到确保不会发生的方法。开发人员的心态有望更加乐观,专注于为了让事情顺利进行而必须发生的事情。
我不是考虑将TDD作为测试代码的一种方式,而是考虑将TDD作为指定系统行为的一种方式。这导致我创建了非常不同类型的测试,这些测试往往对未来的变化更具弹性,因为我正在验证行为而不是测试代码片段。
“单元测试”一词也可能有些误导。如果我们在编写代码之前编写测试,那么它实际上不是测试,因为当我们编写代码时,还没有任何测试。在这一点上称它为测试有点奇怪。相反,我喜欢将其视为一种假设。当我们在编写代码之前编写测试时,我们假设代码将如何表现,我们需要传递什么以及它将返回什么。
(这一点,国外的软件界似乎把Testing和Checking区分的特别清晰,作者说的假设是一种Checking,testing更类似于一种探索)
这类似于我们接近科学的方式。我们不随机进行实验。我们总是从一个假设开始:我们试图证明或反驳的东西。然后我们可以设计一个实验来证明或反驳我们的假设。将您的测试视为假设,并将您编写的代码视为证明该假设的实验。
但是,更大的误解,我发现人们在尝试做TDD时真的被挂断了,就是他们认为“单位”的意思。对于大多数开发人员来说,当他们在“单元测试”中看到术语“单元”时,他们会想到一个代码单元,比如方法或语句块,甚至是单行代码。这不是“单位”在这种情况下的含义。据我了解,采用“单位”一词来强调功能独立的行为单位。
理想情况下,我们所追求的行为直接支持我们试图实现的验收标准。当单元测试也是验收测试时,我们可以免费获得需求可追溯性和可验证性。
“行为单元”可能涉及多个协作工作的对象。例如,为了测试围绕拍卖的出价规则,可能需要卖方对象创建拍卖对象和出价者对象以对该拍卖进行出价。有些人会称之为集成测试,因为它涉及多个对象的交互。我把它称为单元测试,因为我正在测试一个单位的行为,即出价。
我经常发现,当我们专注于构建满足验收标准的功能时,我们编写的代码维护成本要低得多,因为设计更易于理解和扩展。
2.使不可测试的代码可测试
学习TDD的第二个关键因素包括掌握一系列技术,使不可测试的代码可测试。许多现有代码很难测试,当我们必须与该代码进行交互时,很难对其进行测试。
我在访问的许多公司的代码中看到的一个主要问题是,为了使用服务,客户端将实例化然后直接调用该服务。从外部来看,服务和服务的客户似乎是一样的,不能分开。但是当在系统中一遍又一遍地完成这一过程时,它会使系统成为一个纠结的老鼠的代码嵌套,这是不可能独立分离和测试的。
该问题的一个解决方案是称为依赖注入的技术。您可能熟悉依赖注入框架,例如Spring。但是您可以手动注入依赖项,而无需使用框架。我们不是让对象实例化服务然后使用它,而是将实例化委托给不同的对象,然后将引用传递给使用它的客户端。
允许将对服务的引用传递给服务的使用者允许我们在测试时传递假信息。这是一个简单的概念,对于制作小的,可测试的行为单元和分解整体代码至关重要。
我可以传递几种伪造来替换依赖。一种方法是通过简单地继承依赖项并覆盖代码与之交互的方法来创建手工模拟。您可以调用mock的重写方法,而不是调用真正的依赖项,它可以返回任何有意义的东西。请记住,我们的目标是测试代码与外部依赖的交互,而不是依赖本身。
3.获得体验TDD
拥有编写良好行为测试并能够编写良好,可测试代码的技能只是掌握TDD所需的一部分。掌握TDD的第三个也是最重要的成分正在经历这样做。当开发人员完成测试驱动的开发并看到他们的测试如何立即捕获问题 - 以及他们的代码结果有多好 - 他们开始参与项目的TDD。
在新开发需求的项目中学习TDD很有帮助,因为在遗留代码上进行测试驱动开发会有很多复杂因素。这本身就是一个完整的研究领域,并且有一些关于这个主题的优秀书籍。我认为每个专业软件开发人员都应该阅读Martin Fowler的Refactoring:改进现有代码的设计。如果您正在使用遗留代码,那么您还应该阅读Michael C. Feathers的遗留代码的有效工作 。
当我第一次开始向软件开发人员讲授测试驱动开发时,我给他们讲了TDD究竟是什么以及如何使不可测试的代码可测试。他们知道该做什么,但我们没有在一个项目上一起练习TDD,所以它没有坚持下去。六个月后我会回去,团队中没有人再做TDD了。
但是当我开始使用TDD作为培训的一部分进行十二小时的实践练习时,我看到人们做了一个彻底的转变,因为他们自己看到了做TDD的好处。这实际上是我们学习和获得新行为的唯一方式:通过做到这些并证明自己是有价值的。你没有听到别人谈论某个主题的经历。
了解TDD究竟是什么,了解如何使不可测试的代码可测试,并获得在项目中体验TDD的好处的实践是掌握TDD的三个关键因素。我发现,当开发人员拥有这三种成分时,他们对TDD感到兴奋,并继续在他们的项目中做到这一点。
中心思想就是实践,实践,再实践!
网友评论