UML软件工程组织

 

 

第4代白盒测试方法实践之“使用VcTester实施持续集成的组织管理模式”
 
作者:wayne_chan 来源:CSDN
 

本文描述在VcTester的IDE环境下实施持续集成的组织管理模式,也即,先理解持续集成在VcTester环境大致是如何组织的,涉及源码与测试代码如何维护,版本管理如何组织等。在了解这些基础知识之后,我们在另一篇文章《使用VcTester构造持续集成及每日构建平台》中再详细介绍如何使用VcTester工具一步一步去操作。

为什么要持续集成?

持续集成是一种先进的研发模式,极限编程、微软每日构建等实践都验证了它是高效的开发手段。Steve McConnell在《IEEE Software best practices: Daily Build and Smoke Test》一文中总结了这种操作模式具有如下优点:

1、 能最小化集成风险

项目组可能遇到的一个很大的风险是,项目组成员根据不同的系统功能各自开发不同的代码,但是当这些代码集成为一个系统的时候,也许系统完成不了预期的功能。这种风险的发生取决于项目中的这种不兼容性多久才被发现,由于程序界面已经发生了变化,或者系统的主要部分已经被重新设计和重新实现了,相应的排错工作将非常困难和耗时。极端情况下,集成的错误可能回导致项目被取消掉。每日构造和冒烟测试可以使这种集成错误变得非常小,而且便于解决,防止了很多集成问题的产生。

2、 能减小产品低质量的风险

这种风险是和集成不成功、集成出错相关联的。每天对集成的代码做一些少量的冒烟测试,即可杜绝项目中那些基本的质量问题。通过这种方式,使系统达到一种周知的良好状态,维护这样的系统可以防止系统逐步恶化到耗费大量时间排查质量问题的地步。

3、 能简单化错误诊断

当系统每天都进行build和测试时,系统任何一天发生的错误都能够变得十分精细,便于排查。比如在17日系统还运行正常,18日就出错了,那么只需要检查这两次build之间的代码变化就可以了。

4、 能极大鼓舞项目组的士气

看到产品的不断成长,能够极大的鼓舞项目组的士气,有时甚至不管这个产品到底用来做什么。开发人员可能会为系统显示了一个矩形而感到激动。通过每日构造,产品每天进步一点点,保证项目士气的持续高涨。

大家可能认为每日构建是一件很难的事,其实不然,只要方法得当、流程措施有力,每日构建还是容易做起来的。想象一下,Windows NT是无比复杂的系统,包括了560万行代码,共有4万个源文件,微软仍能坚持每日构建。对于我们只有十数万行规模的产品,做一做每日构建又能有多难呢?!

每日构建、冒烟测试、持续集成

这几个概念存在一些差异,前两者来源于微软件的实践,后者持续集成意含较为广泛,虽非XP的专有实践(实际上,在XP实践之前已有不少公司在实践持续集成了,象IBM早在上世纪60年代就尝试集成迭代开发模式,类似持续集成,提法不同而已),但许多人认为它发端于极限编程。

每日构建指研发中的版本能每天自动构建,每日构建常配合冒烟测试,而在XP的持续集成概念,应包括版本能自动构建,同时遵循“代码写一点测一点”的开发模式,包括了测试实践方面的一些规定。

应该说版本构建是公共的,持续集成的相关测试是私有的,如下图,每日构建由服务器自动完成,生成最新版本供全产品人员使用(甚至用于产品发布),不同角色的测试人员各自取最新版本各自展开工作,即使同一阶段的测试工作,不同测试人员所针对的被测特性各不相同,每个人都针对其中的一个剖面开展工作。

测试脚本该由谁来维护

持续集成实践集中于编码与白盒测试阶段,通常是自己编码自己测试,既然要坚持持续集成了,日积月累的测试脚本该由谁来维护呢?是不是每次测试后都将大家的脚本合并一起?许多人都对这个问题感到困惑,从表面上看各人的脚本应该合一起维护,但合一起后,又如何维护呢?大家都互不熟悉别人的脚本是怎么写的。

第4代白盒测试的方法论指出,测试代码也是一种产品代码,应与产品源码对等的看待。理解这一点,我们不难推断,测试脚本也应该是“谁编写就归谁维护”,因为产品源码就是这么做的。

另一个问题,白盒测试用例需不需要合并?在单元测试阶段,测试用例是不必合并的,谁写的用例就归谁使用,也归同一个人维护,不存在把大家的用例合并起来的需求。当然,特定情况下,比方从各人维护的用例库中抽取部分基础用例,构造冒烟测试集,这时是有合并需求的,但该情况应视为特例,因为构造冒烟测试集,只是简单的从已有用例中挑选,选出用例的维护责任不应发生迁移。

在集成测试阶段,测试用例也不必合并,如果是自己设计用例测试自己写的代码,这类用例没必要与别人合并。如果是较高层次的集成,不是自己测自己了,比方系统级集成测试,由专门的测试人员针对模块接口(或子系统接口)编写用例,这时,一人写脚本测试多人编写的代码,或者多人写脚本测试多人编写的代码,其用例设计可能有合并的需求。当然不合并也可以,无非回归测试时,按多个工程的测试集分别去跑,若要合并,目的也不外乎让用例维护更方便些,我们把多人设计用例看成工作分摊的一种手段,合并用例的过程可视作用例设计的固有过程,也即,合并前每个人都维护自己的测试工程,合并后,各人的测试工程在新工程下体现为一个测试集分支,在VcTester中,测试集是可以层层嵌套的,测试集合并后要处理各个集合之间的相互关联、或相互影响的关系,这自然应被看作一种测试设计过程。所以,如果将甲和乙设计的测试用例合并,合并工作由丙承担,合并后所有用例又转移给丁维护,那么,合并后甲、乙、丙都得向丁交接工作。

总结一下,代码与用例的维护责任遵循一个原则:代码或用例是谁写的就该由谁来维护,将多人维护的用例合并,其过程也是一种测试设计过程,这完全类似于功能模块的集成过程,将多人开发的模块合起来是联调,没人把联调不看作一种开发工作。

日常调试与规范测试

VcTester遵循第4代白盒测试方法的理念,将测试脚本与产品源码对等的编辑、调试、测试与维护,如下图:

编辑及调试产品源码,与编辑及调试测试脚本不仅在同一IDE环境下进行,而且几乎同时或者说紧密交叉着推进,一次调试中我们几乎无法区分当前操作是为了把源码调通过,还是为了把脚本调通过。结果评估也是,考察产品功能是否正确,与判断当前测试是否通过几乎重合,测试通过常意味着产品功能跑正确了,反之亦然。

从上图还可看出,产品源码或测试脚本的调试方式(Debug方式)运行,与发布方式(Release方式)运行存在一些区别。首先,Debug运行是日常工作的主体,Release运行是阶段性工作,或者说,将日常调试成果按规范方式运行一遍;其次,Debug方式下针对脚本的工作与针对源码的工作混杂一起,两者并不严格区分,而Release方式下两者是严格区分的,源码编译后成为用于发布的产品,批量运行脚本则是正规测试,如回归测试、冒烟测试等。

由上述差异,我们不难看出,日常调测与规范测试在持续集成实践中应该分开操作的,日常调测遵守一种工作形式,规范测试遵守另一种形式。在VcTester环境下,调试是很自由的,任意写一段脚本,选中执行就能读写变量、调用被测函数,此方式下,编写脚本及产品代码不拘形式,不必时时按照规范的格式进行,而规范测试则有严格要求,至少,产品源码与测试脚本能编译通过,运行产品或运行脚本要使用一个确定的调用入口。

再进一步,持续集成的日常调试中,在VcTester集成环境下调试源码与脚本,需支持将当前工作文件从版本机checkout或checkin,也支持VC工程自动构建(将build/rebuild/clean等操作集成到VcTester环境),我们可借助菜单或快捷键完成这几种操作。但开展规范测试不必再依赖VcTester环境,写一个批处理文件用DOS命令就把需要的源码文件或脚本模块从版本机取出来,也用DOS命令自动编译被测工程,及启动被测系统运行。

所以,理解了上述日常调测与规范测试两种工作形式,我们就不难理解VcTester为什么要采用“远端交互运行”与“本端自动运行”这两种模式,更详细信息请参考《VcTester共享版使用手册》中“远端模式与本端模式”一节。

持续集成是以开发人员为主体的工作,开发人员自己写代码,同时自己编写用例进行白盒测试。前面提到这些测试操作是私有的,每位开发人员都在同一被测工程的某一视图展开工作。所以,在VcTester集成环境中他只需打开自己关心的几个被测文件与用例文件。日常调试时,被测工程使用一个宏开关控制当前系统处于“交互运行”模式,而回归测试时,自动构建服务器定义特定宏开发编译出“自动运行”模式下的被测程序,每位开发人员可在他的桌面平台编写一个批处理程序,把从服务器获取测试版本、启动测试等步骤集成在一起,运行该批处理程序就启动规范测试了。

持续集成的组织形式

实施持续集成不仅是IT工具的问题,更是流程管理的问题,如果流程不规范或管理不恰当,也常常导致持续集成做不下去。前面我们理清了用例的维护方式,以及日常调试与规范测试的区别,这两个容易误解的问题解决后,我们再讲讲持续集成该如何去组织。当然,法无常法,道无常道,持续集成应用于不同企业有不同的工作方式,这里我们只讲述持续集成的一般组织形式,以及实施过程中的注意事项。

实施持续集成首先要具备一个良好的组织机构,至少,要指定一个每日构建负责人,可以由版本管理员兼任,如果在大规模的研发团队中,不妨设置一个专职的构建负责人,该负责人将对维持正常的每日构建运作承担主要责任。之外,还得有质量或测试方面的负责人,确保每日构建生成的版本有相应的动态测试或静态测试跟进,并保证测试达到某一质量目标。

其次,制定严格的管理措施,应强调:

1. 每日构建应每天都做,即使源码没有更新,也要每天去build。

因为构建是自动进行的,不带来额外负担,但如果有不做构建的借口,很有可能让每日构建留于形式,到最后趋于消亡。
强调“每日”是重要的,如Jim McCarthy所说,把每日构造看作是项目的“心跳”,没有“心跳”的话,项目也就死了。还有Michael Cusumano 与Richard W. Selby描述了另外一种隐喻,把每日构造比作项目的“同步脉冲”,不同开发人员写的代码在他们的“脉冲”之间肯定都会存在“同步”的差异,但是必须有这样一个“同步脉冲”,使得这些代码能够组合为一个整体。当项目组坚持每天把这些不同的“脉冲”组合到一起的时候,开发人员脱离整体的情况就很大程度得到杜绝。某些项目把这个过程简化为“每周build”,必然带来问题,当某一次build失败,可能要回溯好几周才能找到失败原因,如果发生这种情况,已经得不到经常build的好处了。

2. 保证导致构建中断的任何问题立即解决

任何导致构建中断的问题都是高优先级问题,要求有充分措施保证它尽快解决。有些公司甚至要求即使在半夜也能找得到相关人员,编程人员谁中断了编译,哪怕凌晨两三点钟也得回公司把他的问题先解决。实施每日构建的团队应遵守这样的规则:不管谁中断构建,谁就得伺候后面的构建过程。

3. 应有措施保证每次代码checkin有修改记录,每日构建负责人还要维护每日构建的操作记录,构建记录有助于回溯某些BUG从哪个版本开始引入的。

4. 需要始终保持“写一点测一点”的开发模式,使用VcTester工具应严格遵循“红绿灯通行机制”(参见《第4代白盒测试方法介绍(理论篇)》),对测试设计不能及时跟进的行为要有控制措施。

然后,持续集成还要有恰当的特性开发进度配合。请注意:

1. 应事先规划各个基线版本,包括不同层次的版本,如路标版本、特性版本等,明确各个版本的交付日期

2. 在恰当时间点冻结特性、冻结代码

一个计划中的版本通常包括“必须实现的特性”与“希望实现的特性”,后者在交付之前会明确成“实现特性”和“不实现特性”,一般情况下,在项目到达2/3进度时,应召开冻结会议来明确哪些特征要不要实现,当特性冻结后,任何计划外的新功能就不再允许添加了。
配合特性冻结还有一个“代码冻结”,当所有规划内的特性都开发完成,就进入“代码冻结”,此后在指定版本上只能是为解决BUG才修改代码。

3. 要让持续集成行之有效,还得将开发任务分解到足够小

这一点很重要,团队成员间的协调配合对持续集成操作影响很大,项目经理应恰当的分解任务,按照微软的实践,每项任务细化到半天至3天的工作量,才对持续集成较为有利。如果任务超过一周,人们通常不会充分、通盘的考虑它,而某任务小于半天就完成,再细化它就多余了。

最后,我们再强调一下,持续集成应坚持质量优先的理念,凡有BUG应先解决BUG才能进入下一步开发,每完成一项开发任务(通常以两、三天为单位),测试跟进后,若测试覆盖率指标或测试程度指标没达到要求时,应先增加用例设计使测试较为充分后,才能进入下一个功能开发。质量优先原则与进度要求并不矛盾,通常坚持质量优先并不拖后进度,而坚持进度优先的,常常是进度后拖了,质量又没得到保证。

参考文献:

1. Steve McConnell, "IEEE Software best practices: Daily Build and Smoke Test"

2. Microsoft Press, 1995, "Dynamics of Software Development"

3. ezTester(China),Wayne Chan,《第4代白盒测试方法介绍(理论篇)》

4. ezTester(China),Wayne Chan,《第4代白盒测试方法介绍(VcTester实践篇)》

5. ezTester(China),《VcTester共享版使用手册》

6. ezTester(China),《使用VcTester构造持续集成及每日构建平台》

7. ezTester(China),《VcTester持续集成框架的应用价值》

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号