对话马丁·福勒(Martin Fowler)——第五部分:测试驱动开发
简介
在这部分,Fowler 描述了测试优先设计的从容品质,定义了何为单一思考,并且分析了单元测试和功能测试的区别。
逐步设计
Bill Venners:在进化型设计中,接口的设计是否是逐步完成的,每次只设计一小块?
Martin Fowler:没错。比如说,当我构造一个 Money 类时,在没实现“加法”功能之前,对于“乘法”功能我连考虑都不会考虑。只专注在“加法”功能上,不要想其它的事情。定义“加法”的接口,实现它的代码。然后再做下一步。
Bill Venners:我还是更习惯于这样的方式:好,让我们来看看 Money 这个类,它应该有哪些职责?需要提供哪些服务?先定义接口而不要管代码,把这些接口都定义清楚、一目了然,然后是写代码,接下来测试、实现,测试、实 现…… 我仍然倾向于把整个系统分为子系统,然后再分为子系统的子系统,然后批量地设计需要用到的接口,对于类也是如此。
Martin Fowler:我之所以采用逐步设计以及先写测试的方法,是因为这样做使我有了一个简明扼要的任务列表。在每个阶段的结尾,我都有一些已经做完的事情。于是我对自己说,好吧,这些东西是完成了的,把它们添加到已有的代码中吧。它们做了它们应该做的,而且是以正确的方式。
从容不迫的感觉
Martin Fowler:测试优先设计会使你体会到一种难以言传的从容不迫之感。你的进展其实非常快,但却不会让你感 到很紧张,因为你为自己设定的都是一些微目标(micro-goals)。在每个时间点上,你知道自己是在实现某一个微目标。一旦测试通过,该目标就实现 了。这是一种很平和的过程。它缩小了你的关注范围。你不需要去考虑每一件事情,只需要专注于某一小块功能。你实现了这个功能,然后重构它,使得其中每个环 节的设计都近于完美。然后再进行下一步。我以前用的是你所描述的方法,我不得不常常问自己,“这个东西的接口是什么?”而现在,我转向了增量式设计 (incremental design),并且觉得这种方式要大大由于之前的方法。
Bill Venners:好吧,我也会试试这种方式。
Martin Fowler:你只需要花少许时间来尝试一下。最好是跟以前这样做过的人在一起。只管做好了。
我在写《企业应用架构模式》(Patterns of Enterprise Applications Architecture Design)这本书的时候,曾碰到过这样一个增量式设计的例子。当时,我需要构建一个关联表映射(associative table mappings)的模式实例。假如在内存中你有一个多对多的关系,并且需要把它持久化到一个关系型数据库中。这时,你需要一个额外的连接表。因此一共有 三张表。有很多种方法可以将数据从数据库中读入到内存里:有一种比较简单的办法,但是需要执行多个 select 语句;也有一种比较快的方法,可以只用一个 select 语句,但是当需要把返回的数据提取出来并拆分到不同的对象中时,就会很别扭。
我用增量式设计构建了这个模式实例。起先,我针对三张具体的表和两个具体的类编写了一段写死的代码,根本就没有考虑通用化的问题。我只是 让这个非常特定、具体的例子能够运行起来。在通过测试之后,我着手重构这个例子以使它的应用范围更广一些。花了一点时间之后,我就得到了一个通用的机制。 我所要做的一切,就是写一个很小的映射类,就能够让这个例子对任意的表和类都适用。
我发现,从具体的实例入手然后再把它重构成一个抽象的例子是非常容易的;反之,如果从抽象的例子入手而把它应用到具体的案例中,则要困难 得多。我还发现,前者会给人一种更平静和从容的感觉,而实际的进展又非常之快。我能够始终清楚目前我在哪里,又在做什么。我对进度的把握也更加得心应手, 再也不会有那种“何时才能让这段代码运转起来”的无力感。
单一思考
Martin Fowler:Kent 在他的新书中与我不约而同地使用了同一个词——单一思考(monological thinking)。“单一”是指在任一时刻,都只使用一种逻辑,一种思考模式。当我构建前面提到的那个例子时,我只考虑如何使那个很具体的例子运行起 来;而当我进入到重构阶段时,我只考虑如何抽象化那个具体的例子。我不会同时去考虑两件事情;一次只做一件事情。我发现这样做的体验非常宁静而愉快。
Bill Venners:听起来似乎增量式设计是处理复杂性的一种解决之道,毕竟我们的大脑是有限的。那么,你认为先写测试或后写测试在多大程度上属于一种个人的选择?是否某些人天生适合一种,而某些人天生适合另一种?
Martin Fowler:这很有可能。人的个性很可能会有所差别。不过,现在还很难下结论,因为尝试过测试驱动开发的人还是少数。它在极限编程的人群中非常普及,但这部分人仍然只是程序员群体中极小的一片。
我建议你找个以前尝试过测试驱动开发的人陪你一起试试,这样你会有更好的体会,毕竟这与你平时的直觉是相反的。很抱歉我们没有时间做这个 尝试,尽管我是非常地愿意。我敢肯定,你会说,“我们干嘛要做这么小的一步?不值得这么做嘛!”而我则会说,“相信我。完成这些很细小的步骤。”这种情况 我见得太多了。我曾见过一个人第一次跟 Kent 一起编程。那个家伙研读过极限编程,并且对之很赞同。他应该是已经做好了充分的准备了。尽管如此,当他看到 Kent 所做的一些极细小的步骤时,下巴不止一次地掉了下来。最终他认识到,测试驱动开发完全不是他所期待的那样。
单元测试
Bill Venners:单元测试中的“单元”是什么意思?能给单元测试一个定义么?
Martin Fowler:哦,这很难。最粗略地讲,它是一个类。但随着你与之打交道越多,你就会意识到你是在测试功能 的一小块区域,而这一小块区域有可能是一个类的一部分,也有可能是几个类合起来的作用。我这里只是粗略地一说,不过,如果你想开始试试的话,可以把单元测 试看成是为每个类编写个测试案例。
Bill Venners:之所以把它称为“单元”测试,是因为你所做的测试是针对程序的单独的小块。为了使整个程序稳定运行,需要每个组成部分都能稳定运行;为了使每个组成部分稳定运行,则需要通过单元测试来对它们进行单独测试。
Martin Fowler:这是关于单元测试由来的解释。极限编程中的单元测试与传统的单元测试有所不同。在极限编程中,你并非割裂地去测试每个单元,而是去测试每个类及其与其他类的联结。
Bill Venners:单元测试和功能测试有什么不同?
Martin Fowler:在极限编程圈内,现在把功能测试称为验收测试(acceptance test)。验收测试更倾向于把系统视为黑箱,测试系统从端口到端口的表现。你可能会有针对在领域和数据库映射层中一些个体类的单元测试。这些单元测试 中,可能绝大部分都不需要连接数据库。你可能会把数据库排除在外。但是对于功能测试来说,当然是希望所有的东西都被联结起来。
Bill Venners:什么时候停止编写测试?你在《重构》一书中写道:“在某个节点,测试的回报会减小。编写过多的测试有可能使你感到沮丧,进而连一个测试都不写。你应该注意把握这个度。”那么,这个度在哪里?
Martin Fowler:这个要问你自己,程序中哪部分是你不希望发生变化的?我自己会做这样一个测试,问一问是否存 在程序中某行代码可以被注释掉而测试仍然可以通过的情况。如果有的话,或者是你少写了一个测试,或者是程序中有多余的代码。类似的,针对任何一个逻辑表达 式,是否可以将它取反?哪些测试会通不过?如果没有测试通不过的话,那么你显然需要再写一些测试,或者清除一些代码。
Bill Venners:听起来似乎可以将这个过程自动化。
Martin Fowler:事实上,有专门的程序做这个,叫 JesTer。问题是,它运行所需要的时间太长了。它每做一个小改动,就要把整个测试都重新生成一遍。
分享到:
相关推荐
本书深入详细地介绍了Java体系结构及其内部细节,了解这些内容才能更快速地编写更高效的程序。
全书共分20章,解释了Java虚拟机的体系结构,包括Java栈、堆、方法区、执行引擎等;描述了Java技术的内部细节,包括垃圾收集、Java安全模型、Java的连接模型和动态扩展机制等。
深入Java虚拟机,注意不是深入理解Java虚拟机。下载之前请考虑
讲述java虚拟机 唯二的书。本书作者曾因本书荣获专业技术杂志《Java Report》评选的优秀作者奖,细心的读者可以从网上找到许多对本书第1版的赞誉。作者以易于理解的方式深入揭示了Java虚拟机的内部工作原理,深入...
深入JAVA虚拟机是中文的,但是内容是图片
Bill Venners关于设计模式的访问,说得很抽象,大家就当联系英语了。
本书讲述了Java虚拟机一运行 所有Java程序的抽象计算机,还讲了几种与虚拟机密切相关的核心Java API。本书通过分析讲解、可运行的示例、参考资料和applet (它作为文中所述概念的交互式例示),提供了Java技术的深人...
Inside Java Virtual Machine by Bill Venners 中文PDF版
Bill Venners的《深入Java虚拟机》所有源代码
Bill Venners 的 Inside the Java virtual machine,少见的英文扫描版,第一版
7zip format Programming in Scala, 2nd Edition, recommended by scala-lang.org. A comprehensive step-by-step guide by Martin Odersky, Lex Spoon, and Bill Venners
Scala编程第三版英文原版,Martin Odersky, Lex Spoon, Bill Venners编著,带目录 快学Scala第二版英文原版,Cay S. Horstmann编著,不带目录
by Martin Odersky, Lex Spoon, and Bill Venners This book is the authoritative tutorial on the Scala programming language, co-written by the language's designer, Martin Odersky. This second edition ...
《Scala编程》介绍了一种新的编程语言,它把面向对象和函数式编程概念有机地结合为整体,...Bill Venners Artima的总裁。撰写了许多关于、Java的文章,是《深入Java虚拟机》的作者,以及Scala Test测试框架的设计者。
Programming.in.Scala 第二版和第三版合集,作者 Martin Odersky / Lex Spoon / Bill Venners, 内容为全英文。 个人觉得写得不错,好过那本 Programming Scala (一词之差,封面是一只马来貘)
《深入Java虚拟机》之英文版,作者:【美】Bill Venners, PDF 格式, 已修正文字重叠问题.
摘要:本文是Bruce Eckel和Bill Venners对C#首席架构师Anders Hejlsberg的采访,在本文中你将可以了解为什么C#默认声明是非虚拟化方法,而是采取和Java、C++中相反的解决方案,这一切跟版本控制以及方法覆盖有关系。...
by Martin Odersky, Lex Spoon, and Bill Venners This book is the authoritative tutorial on the Scala programming language, co-written by the language's designer, Martin Odersky. While mostly complete,...
Bill Venners 是Artima Inc. 的主席,Artima 开发者网站(ww.artima.com)的发行人,以及Escalate Software, LLC 的联合创始人。他著有《Inside theJava Virtual Machine》,这是一本面向程序员讲解Java 平台架构和...