4.4.1 调整周期
当你开发代码的时候,你会设计一个应用程序变成接口,然后实现接口所提出的功能.当你进行单元测试的时候,你通过一个方法的API来验证功能
4.4.2 TDD两步走
前面,我们说过通过[测试,编码,(重复),提交]这样一个流程,TDD加快了开发的周期.可问题在于这还遗漏了一个重要的步骤.更应该像这样来运作:[测试,编码,重构,(重复),提交].
TDD的核心原则是:
1. 在写新代码之前写一个失败的自动测试.
2. 消除重复.
消除重复这个步骤确保了你写的代码不仅能通过测试,还具备可维护性.当你清除了重复之后,你能够增加内聚,减少依赖.这些都是长时间保存而不变质的代码的特点.
别的编码实践鼓励我们编写可预知改变从而达到可维护性的代码.与他们不同的是,TDD鼓励我们通过消除重复来编写可维护的代码.遵循这个实践的开发者发现.有测试撑腰的并且划分良好的代码自然而然地可以简单而且安全地承受改变.TDD给了我们自信,让我们的问题解决,明天的问题明天解决.
4.5 在开发周期中的测试
在开发周期的不同地方和不同时间都会有测试.让我们首先介绍一下开发生命周期,然后以它为基础来决定何种类型的测试将在何时被运行.图4.9给出了一个典型的开发周期,这样的一个开发周期我们在小型或大型的开发中都广泛应用.
生命周期被分成四到五个平台(platform)
开发平台: 这是编码发生的场所.它包含开发者的工作站.它的一个重要的功能是提交(commit) 或check in(取决于所使用的术语);这样的提交会有几次,提交到你的公共源代码控制管理工具.一旦你提交了,其他人能开始使用你所提交的东西了.但是只能提价能工作的部分也是很重要的.为了能知道它是否能正常工作, 一个典型的策略是采用自动构建,并且在每次上传之后都运行它.
集成平台(integration platform):这个平台的目的是集成各个不同部分来构建应用程序而且要确保他们在一起能协调地工作.这一步是很有价值的,因为通常能在这儿发现问题.是因为它很重要.所以我们希望它能自动执行.它被成为持续集成.并且,通过把自动构建应用程序作为构建过程的一部分,这也是可以达到的
验收平台/压力测试平台:取决于你的项目预算,这可以是一个或两个平台.压力测试平台在加载以后执行应用程序,并验证它是正确的.验收平台是项目的客户.
成品(前)平台
让我们来看一下测试是如何在开发周期中发挥作用的.图4.10说明了在每一个平台上你能进行的不同种类的测试:
在开发平台,你执行逻辑单元测试(这些测试是能脱离环境进行的).这些测试执行得非常快,你通常从你的IDE来执行它们以验证你对你的代码所做得任何改动没有损坏其他部分.在你提交代码到你的SCM之前,你也可以通过你的自动构造来执行它们.你应该执行集成单元测试
集成平台通常会自动运行构造过程,生成包,配置应用程序,并且执行单元测试和功能测试,通常只是所有功能测试得一个子集在集成开发平台下运行,因为相对于目标平台,它只是一个简单的平台,缺少一些元素
在验收平台/压力平台上,你将执行和集成平台相同的测试,此外,你还要运行有压力测试和负荷测试.验收平台同终的运行平台非常相似,并且能够执行更多的功能测试.
尽管在预期的运行平台下测试是一个很好的习惯.这样的话会保证你是在一个一切都是正确的环境下校验的.
4.6 小结
改变的步伐在加快,项目的时间框架在缩短,而我们需要对变化作出快速的反应.另外,开发过程正在改变----让开发成为代码的艺术还不够,还应当让开发成为编写解决方案的艺术.
为了能跟上迅速变化的脚步,我们必须打破异步开发模式,在这种模式中,软件测试是在开发完成以后由另一个独立的团队进行的,当改变和速度变得极为重要时,把测试留到后不那么合适了.
第五章:Junit自动化
在这一章里,我们将学习直接支持Junit的三个产品:Ant,Maven以及Eclipse.Ant和Maven是可以和任何Java编程环境配合使用的构建工具,Eclipse是一个集成开发环境(IDE).我们将会展示如何高效地结合使用Junit和这些环境,以及如何把Junit测试的执行自动化.在这章的后,你将会知道,如何在你的电脑上配置环境来构建Java项目,包含如何执行Junit测试以及如何创建Junit报告.
5.1 生命中的
为了使单元测试有效实用,它们必须是开发流程的一部分.大部分的开发周期开始于从项目源代码中导出模板.在进行任何修改之前,谨慎的开发者会首先运行全套的测试工具.许多团队有工作库必须通过所有单元测试的规定.在开始你自己的任何开发前,你必须留意没有谁违反这条”全绿规定”.你必须保证你的工作进展是已知的基线开始.
接下来是编写新的用例的代码.如果你是测试驱动开发的实践者,你会先开始针对用例编写新的测试.一般来说,这项测试表明你的用例未被支持.一旦你写下了实现用例的代码,状态条将变绿,这样你可以提交你的代码了.
非TDD实践者将实现用例并且编写测试验证.一旦状态条变绿,代码和测试可以提交了.
5.2 从Ant中执行测试
编译和测试像第三章中的DefaultController类这样一个单独的类是不难的.如果你的工具只是库中Javac编译器,那么编译一个包含有多个类的大项目将是令人头痛的.在数目不断增加的类之间互相牵扯.于是越来越多的类得处于classpath上以便编译器能找到它们.在每次构建中,只有一小部分类会被修改,该编译哪些类也是问题.在编译之后手动重新编译你的Junit测试也同样不方便.
幸运的是,以上问题的答案是令人难以置信的Ant.ant不仅是一个编译程序的强有力工具,也是执行Junit回归测试的解决之道.
5.2.1 不可缺少的Ant
Apache的Ant是个让你轻松地编译和测试程序的构建工具.它是构建Java程序的事实标准.让Ant如此流行的一个原因是它不仅仅是个工具;ant是运行工具的架构.除了可以使用Ant配置和启动编译器,你还可以使用它来生成代码,执行JDBC查询,还有你将看到的Junit整套测试工具.
像许多现在的项目一样,Ant使用一个XML文件来进行配置.这个文件也是构建文件(buildfile),默认情况下被命名为build.xml.Ant的编译文件描述了你想应用在你的项目中的每一个任务.任务可能是编译java源码.生成java文档.
第二部分:测试策略
第一部分介绍用Junit进行单元测试的基本知识.然而,仅仅知道了Junit如何工作,或者如何把Unit用于简单的例子,这都是远远不够的.尤其是当把它用来测试一个真正的应用程序的时候.所以,单独的Junit是不够的,你需要发展出一套测试策略,使你能够对一些真枪实弹的程序进行单元测试.主要问题在于如何孤立地测试每个部分.你在写单元测试代码时,想要一点一点地测试应用程序.那么,你如何把各个功能分离出来,从而独立地测试它们呢?第2部分解决了这个重要问题..
第6章介绍了stub策略,它允许你孤立测试粗粒度的代码部分.在第7章中,你会学习到叫mock objects的新技术,它可以进行孤立的细粒度测试.通过使用mock objects,你会发现这不仅仅是一种对代码进行单元测试的新方法,而且还是一种新的编程方法.第8章把你带入一个全新的领域---在容器中对代码进行单元测试.现在,几乎所有的代码运行在可与之交互的某些容器中.你会学到,当J2EE代码运行在它的容器中时,如何进行单元测试.你还可以通过与mock objects方法进行比较,从而了解这种策略的利弊.
读完第二部分,你会熟悉用隔离方法对代码进行单元测试的这三种策略了.你将做好准备,可以去应付我们旅行的后一步:单元测试各种类型的J2ee组件.