从戴维?恩斯坦教数千软件开发者们如何更有效地以测试驱动开发的10年来,他学会了掌握测试驱动开发的3个关键组成部分:理解它真正是什么,使代码稳定可测,并且获得实际动手经验。让我们看这些因素,找到它在你的项目中为有效地使用测试驱动开发带来什么。
在过去10年来,我有教数千个专业软件开发者如何有效地测试驱动开发的权利。从这些经验中,我学会了测试驱动开发的3个关键因素:理解它真正是什么,使代码确实可测试,并且获取一手的经验。让我们看一看这些因素中的每一个,去看看使用测试驱动开发能有效地在你的项目中带来什么。
1. 理解什么是测试驱动开发
有效的测试驱动开发的第一主要的组成部分是理解它真正是什么。我发现有很多关于如何恰当地做测试驱动开发的错误想法,并且测试驱动开发是那种,如果你做错了,你会经常付出一个很高的代价的实践。
在这篇短的文章中有更多的介绍测试驱动开发,但是我注意到的其中一件事是对人们来讲更有挑战的是人们把测试驱动开发想象成测试或者质量保证的一种形式。我认为在做测试驱动开发时,这是错误心态。
QA的思维模式是在思考可能出现的问题并且找到保证它不再发生的方法。开发的思维模式更乐观,专注于发生的事情,为了事情顺利进行。
不考虑将测试驱动开发作为测试代码的一种方式,我想把测试驱动开发想成系统特殊行为的一种方式。这引导我创造非常不同的测试种类,它趋向于将来更有弹性地改变,因为我正在验证行为而不是测试代码块。
术语“单元测试”也有点误解。假如我们在写代码之前写测试,那么它实际上不是一次测试,因为当我们写它时,没有可测试的东西。在这个点上叫它一次测试有点奇怪。反之,我想要把它认为是一种假说。当我们在写代码之前写测试时,我们在假定代码将如何运行,我们需要通过什么,以及将返回什么。
这类似于我们如何接近科学。我们不能随机运行实验。我们经常开始一种假设:我们正在尝试通过或不通过的东西。我们能想出一个实验去通过或者不通过我们的假设。把你的实验考虑成假设,并且你写的代码是为了使测试作为一种实验通过,来证明这个假设。
但更大的误解是,我发现人们在尝试TDD时真的会挂起电话,这是他们认为“单元”的意思。对很多开发来讲,当他们在“单元测试”里看到术语“单元”,他们想到一段代码,像一个方法或者一段声明,或者甚至一行简单的代码。这不是本文中“单元”的含义。就像我理解它的,术语“单元”被接受成强调一个功能独立的单元。
理想情况下,我们后面的行为是对我们正尝试获取的验收标准的间接支持。当单元测试也是验收测试时,我们自然得到需求可追溯性和可验证性。
一个“行为单元”可能包含一些以合作为工作目的的对象。举个例子,在拍卖中测试投标规则可能需要一个卖方对象来创建一个拍卖对象和一个投标人对象在拍卖中投标。有些人将把它作为一次集成测试,因为它包含一些对象的交互。我把它称为一个单元测试,因为我正在测试投标行为的一个单元。
我经常发现当我们关注于可以满足验收标准的附加特性时,我们编写的代码的维护成本要低得多,因为设计更容易理解和扩展。
2.使不可测试的代码可测
学习测试驱动开发的第二个关键因素是掌握一系列使不可测试的代码可测试的技术。很多已存在的代码是很难测试的,并且当我们不得不和那些代码交互时,很难让它接受测试。
通过我参观的很多公司,我在代码中看到的一个主要问题是为了使用一项服务,一位顾客将被实例化并且直接呼叫那项服务。从外部来看,服务和服务的客户端似乎是相同的,不能被拆分。但是,当这一系统在整个系统中反复进行时,它使系统成为一个纠缠在一起的代码鼠窝,不可能独立地进行分离和测试。
这个问题的解决方案是一种称为依赖注入的技术。你可能很熟悉依赖注入框架的独立性,比如Spring。但是你能手动地注入依赖,不使用一个框架。代替使一个对象实例化一个服务然后使用它,我们委托实例化成一个不同的对象,然后将引用传递给使用它的客户端。
允许对服务的引用传递给服务的使用者,当我们测试时让我们传入假。它是一个简单的概念,对做小的、可测试的单元行为和分开整体的代码是相当重要的。
我可以通过几种虚拟来代替依赖。一个通过简单的归类和覆盖你的代码交互的方法来创造手工模拟的方法。你可以调用你的mock的覆盖方法,而不是调用真正的依赖关系,它能返回任何有意义的东西。记住,我们这儿的目标是测试我们的代码可交互与外部依赖,而不是它自身的依赖。
3.做测试驱动开发的经验
拥有编写良好的行为测试和能够编写好的、可测试的代码的技能,只是掌握测试驱动开发所需的部分内容。第三和最重要的掌握测试驱动开发的因素是体验去做它。当开发者做了测试驱动开发并且看到他们的测试如何立即捕捉问题——结果是他们的代码有多好——他们开始在项目中做测试驱动开发。
在绿色田野项目中学习测试驱动开发是有用的,因为在遗留代码上进行测试驱动开发会有更多复杂性。这本身就是一个完成的学习领域,在项目中有一些优秀的书。我想每一个专业软件开发应该读马丁?福勒的重构:改进已有代码的设计。而且如果你正在遗留代码上工作,然后你也应该读迈克尔?西?羽毛的有效率地同老代码工作——并且不要忘了查看一下我的书,在遗留程序之上:9种扩展你的软件生命(和价值)的实践。
当我首次启动教软件开发关于测试——驱动开发,我给他们关于真正的测试驱动开发以及如何使不可测试的代码可测试的讲座。他们知道该怎么做,但我们没有在一个项目上一起实践TDD,所以它没有坚持下去。6个月后我将返回,在团队中没有人再做测试驱动开发了。
但是当我开始包括12个小时的实践练习使用测试驱动开发作为培训的一部分,我看到人们做了一个彻底的转变,因为他们看到了做TDD的好处。这确实是我们学习和得到新行为的唯一的方法:通过做它们并且向我们证明它们是有价值的。你不能从听别人说一个话题而获得经验。
理解真正的测试驱动开发是什么,知道如何使不可测试的代码可测,在项目中做测试驱动开发获取实践经验的好处是掌握测试驱动开发的3个关键因素。我发现当开发有这3个关键因素时,他们为测试驱动开发而感到高兴,并且在他们的项目中持续做这件事。
原文地址:https://www.cnblogs.com/fengye151/p/11519078.html