我的TDD实践

发表于:2014-11-06来源:uml.org.cn作者:火龙果软件点击数: 标签:tdd
我的TDD实践这几篇文章主要是围绕测试驱动开发所展开的,其中涵盖了一小部分测试理论,更多的则是关注工具的使用及环境的搭建,做到简单实践先行,后理论专精的目的。

写在前面:

我的TDD实践这几篇文章主要是围绕测试驱动开发所展开的,其中涵盖了一小部分测试理论,更多的则是关注工具的使用及环境的搭建,做到简单实践先行,后理论专精的目的。

UnitTest单元测试

简介

1. 单元测试

1.1 定义:“单元测试”就是针对一个“工作单元”的测试,一般意义上来讲是针对一个基础类进行输入/输出测试。与之相关的是集成测试,验收测试等。这里指单纯意义上的“单元测试”。

1.2 特征:

与其他代码相隔离:单元测试只测试一件事,否则应该怀疑是否是测试内容有误。

与其他开发人员隔离:保证最小化的变量影响单元测试,也就是控制变量法。逐渐形成了模拟框架以及依赖注入框架等辅助工具。

有针对性:要做有意义的测试,保证完成那些功能或方法。

可重复:单元测试的最大优势就是可重复,这也是持续集成的意义所在。

可预测:单元测试保证的是---确定的输入得到肯定的输出。

2. 涵盖内容

2.1 单元测试框架(UnitTest):自从2005年TDD开始流行,框架和工具得到了迅猛的发展,这些框架允许定义测试代码,控制测试的执行,还提供了一个应用程序运行测试,并在成功完成测试套件中的每个测试后给出报告。

2.2 模拟框架(Mock):为了仅测试一个方法而不对其他发展产生影响或者被影响,产生了Mock框架。通过模拟另一个类的代码来完成单元测试,同时又充分的隔离了另一个类的部分信息。

2.3 注入框架(inject):为了充分隔离类内部使用的对象,一般采用构造注入的方式或者属性注入的方式,都是将外部初始化好的对象导入进测试类,以进行隔离。

3. 工具比较

3.1 单元测试工具

3.1.1 NUnit:目前.net最流行的工具,由JUnit发展而来,简单易用。 官方网站

3.1.2 MSTest: 也十分的强大,同时也被多种自动编译工具所支持,在VS2010中十分方便创建以及关联测试测试类,使用方便。

这是两个比较主要的测试框架,NUnit更新比较慢,但是开源。两种工具语法标签上大同小异,也都支持“Setup”和“Teardown”方便初始化共享对象。

3.2 模拟框架:

3.2.1 Rhino Mock:免费,使用简单,功能强大。

3.2.2 Type Mock:使用中间语言(IL)在运行时以模拟实现来代替实际实现。商业产品。模拟对象不需要从接口集成,可以模仿第三方类库。

3.2.3 Moq:社区支持,功能强大,使用简单。Moq利用了lambda表达式。语法更具描述性。

3.3 注入框架:

3.3.1 Structure Map:开源容器框架,能够自动模拟容器。

3.3.2 Unity:来自微软设计与实践群组。

3.3.3 Autofac:允许不采用XML文件的情况下进行配置。

“我的TDD实践”系列之TDD概念篇

简介

1. TDD概念

TDD(Test-Driven Development, 测试驱动开发)已经成为现代软件开发中非常重要的概念之一。TDD以测试用例为指导要求开发人员,开发出符合测试用例的程序,然后通过测试用例对程序进行验收,这被叫做“测试先行的开发”。通过,一个很小范围的功能的开发---验收过程,增加软件的内部稳定性,从而在整体上保证了软件的健壮性。这是与传统软件开发流程所不同的地方,也是传统的软件开发所达不到的一种软件开发的“实践方式”。

2. 发展历程

2.1 瀑布开发之前:软件工程的发展初期,由于计算机资源等诸多限制,软件的规模很小,拥有设备的开发人员更多的趋向于“迭代”开发,独立完成功能,然后在逐步完善,这是一种早期的迭代开发。

2.2 瀑布式开发: 随着计算机硬件的提高以及高级语言的出现,开发人员逐渐摆脱硬件的束缚,而逐渐使用高级语言的特性,提高了移植性。有了这些,为大型软件的开发奠定了基础。一般定义一个相对大规模的软件开发(2年或更多),需要经历的一般过程是: 项目启动---》需求分析---》架构设计---》代码设计---》测试---》交付

缺点: 软件测试时间长,每个过程需等待其他过程完成之后才能进行(效率低),成本高,难度大,修改影响范围大。

瀑布式开发就像三峡的船闸一样,每一步都只能等待上一步完成之后才能进行。

2.3 瀑布+迭代开发:单纯瀑布开发的根本缺点是,需求分析是在项目开始之前,而不是在之中进行的,这就要求瀑布开发对最初的需求分析定位十分的准确,对可能的扩展预先估计的很好,但这几乎是不可能的。这时,人们逐渐转向”迭代“和”递增“开发。这一概念就要求把大的瀑布模型分成几个不同的小的瀑布阶段,每完成几个小的迭代然后进行大的迭代开发。这样在一定程度上保证了,可变更性。但是从整体上来说还是典型的瀑布式开发,前后过程仍然受到制约。 

2.4 敏捷开发:业务的变化不可避免,所以软件开发业必须能够适应。包括但不限于:Scrum,XP(极限编程),FDD(功能驱动开发),Clear-Case,ASD(自适应软件开发)。其中TDD属于XP的一种,是从测试先行实践中发展而来。

3. 敏捷开发共同特征及原则

价值观:

个人与互动 》 流程与工具

可用的软件 》 详尽的文档

与客户合作 》 合约协商

响应变化 》 遵循计划

特征:

它们都将团队内部的交流放在首要位置。鼓励不同团队人员经常交流。特别是开发人员与测试人员,架构师与开发人员。

它们注重项目的透明性。如每周的例会,板报等等。

团队成员是相互负责的,勇于承担责任,不推卸责任。

开发人员没有自己的代码基,而团队拥有完整的代码基,每个人都对其负责。

工作是在短暂的开发周期中完成的,一般情况下为一周至两周。

必须包含应对变化的能力。

一个系统的大致框架是提前定义好的,但是详细设计要等实际安排功能开发计划时才会进行。

4. TDD的优点

TDD从一开就保证了代码的质量:鼓励开发人员只开发”最小化“的代码完成特定测试功能。

遵循SOLID原则: SOLID (单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)---Wiki

TDD确保了代码与业务需求之间的高度一致性。

TDD鼓励创建更简单,针对性更强的API

TDD鼓励更多的沟通,与企业,与团队内部。

TDD有助于清除冗余代码

TDD提供了内置的回归测试。

工具

工欲善其事,必先利其器。

对TDD而言,首先是整体设计,然后是功能设计,功能设计中通过编写测试用例来驱动开发。在开发过程中最基本的,最重要的是单元测试。而单元测试工具就成为了争论的热点,本篇不想过多讨论工具的取舍,这些可以参考同系列的其他文章。

TDD理论中很多工具是围绕UnitTest展开的。

“我的TDD实践”系列之SVN架设

1. 介绍:

本文主要是介绍Source control system(源文件管理系统),这是CI的基础,当然你也完全可以用它只做数据存储,并行开发,源代码控制等等,这里就不详细介绍了,网上有很多资料描述SVN以及源代码管理,TFS也是一个不错的选择。

这里我选择了Subversion+TortoiseSVN的选择,因为开源以及应用广泛,免费。

通常所说的SVN其实是分为2个部分的:

服务端Server:Subversion

客户端Client:TortoiseSVN (广泛引用,功能强大,操作简单

a) 意义:

i. 提供获取历史版本功能,恢复错误版本之前的状态。或比较版本之间的不同。

ii. 锁定正在编辑的文件,访问控制锁定,防止提交冲突。(不同产品,实现功能略有不同。)

iii. 良好的版本管理、版本分发。

iv. 提供文档,工具,测试,源代码的一体化管理。

b) 权衡

说明:Centralized集中式管理 与 Distributed分布式管理(要是开源的建议可以分布式管理,反之集中式管理)

Transactional支持事务性与nontransaction不支持事务性(是否支持还原代码版本,很重要。曾经的惨痛教训告诉我,即使能回滚的情况下已经很闹心何况不能还原数据。) 

File blocking文件锁or non-file blocking非文件锁定方式。(文件锁定方式属于乐观锁,即检出时(checkout)有权限的人都可以获取,但是提交时(checkin)会进行版本控制,简而言之,如果你和某人同时改写了同一个文件,一般情况下谁先提交到服务器上,第二个人就无法提交并报告文件冲突。)

2. 环境搭建

Server :Subversion

Subversion官网 (建议下载1.6.x)

Client:TortiseSVN

目前,官网只有1.8.x 64位版本,请找到适合您的客户端。

本文中建议配合Subversion请使用TortoiseSVN-1.6.8.19260-win32-svn-1.6.11版本

步骤Steps:

点击Subversion安装包,并将程序安装到“指定目录”(默认是C盘下),默认安装后重启。
安装完成,测试是否安装成功。
打开CMD程序,输入 svnserve --help。没有提示错误就是安装成功。

3.SVN服务端配置:

a) 在CMD中输入:sc create SVNService binpath= "C:\Program Files\Subversion\bin\svnserve.exe --listen-port 3691 --service -r D:\SVN\Server\RepositoryRoot" displayname= "SVNService" start= auto depend= Tcpip

其中C:\Program Files\Subversion\bin\svnserve.exe是安装程序的路径;D:\SVN\Server\RepositoryRoot是目标路径,在此之前要提前创建好该目录下的RepositoryRoot文件夹。

啰嗦一句,win7下要管理员权限,没有权限会返回“失败5:拒绝访问”。

也可以用批处理的方式注入cmd命令。

成功后会返回: CreatServer 成功。

b) 启动SVNService服务:(管理员权限)cmd 执行 net start SVNService (SVNService是上面定义的服务名称)

c) 使用SVN集成命令(或TSVN创建),cmd-> input:svnadmin create D:\SVN\Server\RepositoryRoot(此路径必须是服务开启的路径)。然后你会在此目录下看到生成了很多文件,具体不一一介绍了,在这个文件夹中创建tags,trunk,branches文件夹。

d) 配置Svn服务端:

在conf文件夹下,

Svnserve文件修改如下:

anon-access = none

    auth-access = write

    password-db = passwd

    realm = My First Repository

passwd文件修改如下:

[users]  

    qq=229063661

至此,服务端配置基本完成,更多的设置文件中有说明,或者去访问SVN中文站,这里笔者要强调一下的是:SVN服务端和客户端的版本要一致,不然可能会出现莫名其妙的错误。更有意思的是,您可以不建立SVN服务端而直接联接Git的开源程序,但目前只支持只读。

4.SVN客户端配置:

a) 安装TortoiseSVN-1.6.8.19260-win32-svn-1.6.11.exe。基本都是默认设置,安装完之后可以更改语言。

b) 完成本地磁盘和Svn服务端磁盘的映射。

i. 在本地文件夹下右键---checkout---按照图片上的设置(注意我是本地所以用localhost,IP可以跨机器访问;我更改了端口3691,所以要显示指明一下,要不然会出错。),最后输入passwd中的用户名和密码即可。(qq:229063661)

至此,SVN客户端也配置完毕了,SVN的使用方法这里就不举例了,网上资料非常丰富,而且大家也可以查看T-SVN的操作手册,或者访问SVN中文站获得更多信息。

“我的TDD实践”系列之CI持续集成

简介

CI(Continuous Integration)持续集成,最重要的服务对象是TDD,它是一个集合概念,包括自动构建build项目,自动分析代码,自动测试,自动邮件报告,自动预编译检查,自动发布等等,这些都围绕一个中心词“Auto”,当然它不能帮您自动完成代码 :)。所有这些操作,直接解放了项目管理者,每日构建集成(Build every day)将会很大程度上提高项目的稳定性,代码的健壮性及随时反馈。

持续集成经典定义:www.martinfowler.com/articles/continuousIntegration.html

持续集成是一种能让团队成员友好“集成”(integrate)工作的软件开发实践,通常每个人最少每日“集成”一次,也就是说每天都要进行大量的“集成”(multiple integrates per day)。每一次集成都被自动构建器(automated build including test)尽可能快的检测集成错误。许多团队开发者发现,这种方法极大的降低了团队简集成的问题,而且能让团队更快的开发出有凝聚力,结合力的软件(cohesive software)。  --- Martin Fowler 

持续集成拓扑图:

从实用性角度来说,持续集成避免了因为某人突然发生的Bug,导致团队的人员必须等待这个Bug被修复,持续集成每日集成则大大降低了这种事情发生的概率或者控制在一个合理发生Bug的时间内(一个工作日)。

1. 什么样的集成“频率”才是合理的?

2. 持续集成具体的优势和劣质在哪里?

2.1. 可能出现的问题:

2.1.1. 增加了维护CI的成本:起初可能是要在配置环境上花费些功夫,但比起使用效率上以及代码健壮性控制上,则CI更有意义。

2.1.2. 需求更改过于频繁,功能复杂:TDD开发的一个原则是“尽可能用最简单的代码完成一个需求,不添加额外的功能,如果需求改变,则让测试部通过,然后重构,即不要一次完成将来可能的任务,只注重当前”。

2.1.3. 增加软硬件成本和团队学习曲线(Study Curve):同第一条定律,学习曲线则可根据团队情况逐渐深化。

2.1.4. 团队成员将不得不编写测试和构建项目:有了这些团队成员可以只关注编写代码和调试代码,比起修复那些被测试人员发现的bug,更多的利用了Coder的个人才能。(啰嗦一句,本人曾深受过那些莫名其妙的bug所带来的危害,有些还是由于其他人的改动导致的,这样不得不F11跟踪代码来理解Bug产生的流程,绝大多数时刻是极其痛苦的。)

2.1.5. 旧项目是否能用CI: 即使旧项目中没有单元测试,也可以用CI中的源代码管理等诸多功能。这里除非有绝对的意义,否则也不建议在旧代码的基础上补充单元测试。

2.2. 应用CI的优势:

2.2.1. 降低软件风险提高软件的质量:测试代码覆盖率越高,提供的稳定性就越高,建议代码覆盖率80%以上,所谓的二八原则?!

2.2.2. 增强项目的透明度:集成服务器持续的反馈集成信息,包括集成是否成功,Bug修复的时间,修复Bug的时间等。

2.2.3. 迅速构建:更快的发现问题,以及要求构建时间平均在1.9分钟左右。

3. 持续集成相关工具介绍:

3.1. 源文件管理系统(Source file control system):SVN ,TFS(VSS),Github。。。。

具体内容请参考,本系列的其他文章:请返回文章前言

3.2. 持续集成服务端(平台):

3.2.1. TFS Server:微软一体化解决方案。

3.2.2. TeamCity:近些年流行起来的CI集成平台,由JetBrains维护。

3.2.3. CruiseControl.Net: 老旧的平台,脚本配置,06年更新过一回。

3.3. 单元测试工具:

MSTest,NUnit

具体内容请参考,本系列的其他文章:请返回文章前言

3.4. 代码分析工具:

FxCop,StyleCop,Ncover

具体内容请参考,本系列的其他文章:请返回文章前言

3.5. 其他工具:

SandCastle文档构建,Mock框架,Inject框架

具体内容请参考,本系列的其他文章:请返回文章前言

持续集成服务端搭建

本节主要叙述几种持续集成服务端的搭建及其中一些小的细节上的说明,由于时间原因,没有更深层次的说明更多的功能特性,这确实是不足之处,待今后有时间补充。

1. CruiseControl.Net(CC.net):

a) 介绍:Thoughtworks旗下产品,免费,需配置脚本文件。

官网:http://confluence.public.thoughtworks.org/display/CC/Understanding+the+alternatives+to+CruiseControl

b) 安装步骤:

i. 下载CCnet:http://sourceforge.net/projects/ccnet/?source=dlp

ii. 点击安装包,进行默认安装。

iii. 安装完之后,如果是默认安装的话,在%Program Files%\CruiseControl.NET\server,找到文件ccnet.config并用记事本打开并编辑。

iv. 网上有很多配置文件,如下是我的配置文件,

c) 手动运行:在安装程序中启动CruiseControl.Net,验证是否成功。

d) 日志文件在:D:\CI\ArtifactWork\buildlogs目录下。

e) 查看相关记录:http://localhost/ccnet(前提是请安装IIS)

f) 客户端使用CCTry 获取反馈。

2. TeamCity

a) 介绍:简而言之,小项目免费,大项目付费。Web配置代替脚本配置。

官网:http://www.jetbrains.com/teamcity/

拓扑图:

b) 安装步骤:

i. 下载:http://www.jetbrains.com/teamcity/download/download_thanks.jsp

ii. 默认安装。(需更改端口防止冲突,选择user account登录)

iii. Web配置:

1. 配置视频:http://www.jetbrains.com/teamcity/documentation/demos/installation_new/index.html

       http://www.jetbrains.com/teamcity/documentation/userguide.jsp

2. TeamCity在线文档:http://confluence.jetbrains.com/display/TCD8/Configuring+General+Settings

3. 登录配置网页进行相关设置,http://localhost:8011/login.html(安装时,更改了端口号为8011防止冲突)

3.1. 点击 Create New Project

3.2. 点击 Create build configuration。(也可先创建一个子项目,然后再新建一个配置)

3.3. 点击左上角的 Create and attach new VCS root, 然后VCS 类型选择SVN,如下配置:

3.4. 保存之后,继续配置:

选择自动构建的方式:选择Microsoft Visual Studio,也可选择其他的构建器,如MSBuild。

3.5. 增加一个Build Feature,这里可暂时不选择,直接跳过此步骤:点击网页右侧的导航栏,选择第4步。

3.6. 在导航中点击第5步:Build trigger

3.7. 这里已经完成了基本配置,更多高级选项请参考TeamCity官方资料。

3.Team Foundation Server(TFS)

a) 介绍:与VS2010集成,一体化解决方案,当然没有免费的午餐。

官网:http://msdn.microsoft.com/zh-cn/vstudio/ff637362.aspx

拓扑图:

原文转自:http://www.uml.org.cn/Test/201308201.asp