资源描述
软件质量之路(1): 软件质量框架
林星 (iamlinx@)
XML error: Please enter a value for the author element's jobtitle attribute, or the company-name element, or both.
林星,致力于研究敏捷理论和优秀的软件设计思想,并将之应用于国内的软件组织。可以通过 iamlinx@和他联系,也可以通过访问 来获得更多的信息。
简介: 软件质量的重要性是不言而喻的,但是当所有人都意识到它的重要性的时候,却很少有人能够清晰的描述出如何才能够提高软件质量。软件质量框架的目的就在于提出一个评价的原型,帮助我们分析一种方法和技术是否能够提高软件质量。本系列文章分 日构建、 测试驱动开发、 建立核心框架、 面向组件的大规模软件架构来进行深入的分析。
标记本文!
发布日期: 2004 年 3 月 01 日
级别: 初级
访问情况 233 次浏览
建议: 0 (添加评论)
平均分 (共 0 个评分 )
什么才是一个高质量的软件?
在讨论软件质量原型之前,我们先回答第一个问题。一个软件之所以被认定为质量优秀,并不是因为它获得了一个省级或部级奖,而是它的内在具备了这样一些特性:
· 满足用户的需求。这是最重要的一点,一个软件如果不能够满足用户的需要,设计的再好,采用的技术再先进,也没有任何的意义。所以这一点非常的朴实,但却是软件质量的第一个评判标准。
· 合理进度、成本、功能关系。软件开发中所有的管理都是围绕着这几个要素在做文章的,如何在特定的时间内,以特定的成本,开发出特定功能的软件。三者之间存在一种微妙的平衡。在Planning XP一书中,专门有一个章节讨论它们。一个高质量的软件的开发过程中,项目成员一定能够客观的对待这三个因素,并通过有效的计划、管理、控制,使得三者之间达成一种平衡,保证产出的最大化。
· 具备扩展性和灵活性,能够适应一定程度的需求变化。当今的社会已经变成一种变化速度极快的设计了。变化就会对软件产生冲击,所以一个质量优秀的软件,应该能够在一定程度上适应这种变化,并保持软件的稳定。
· 能够有效的处理例外的情况。写过软件的人都知道,实现主体功能的工作量其实不大,真正的工作量都在处理各种例外。所以,一个软件如果能够足够的强壮、足够的鲁棒,能够承受各种的非法情况的冲击,这个软件就是高质量的。
· 保持成本和性能的平衡。性能往往来源于客户的非功能需求,是软件质量的一个重要的评价因素。但是性能问题在任何地方都存在,所以需要客观的看待它。例如,一段性能不错的代码可能可读性很差,这就需要进行平衡,如果这段代码的性能是整个软件的关键,那么取高性能而舍弃可读性,反之则取可读性而舍弃高性能。一个优秀的软件能够保持成本和性能之间的平衡。
· 能够可持续的发展。很少有软件组织只开发一个软件的,所以,一个优秀的软件在开发完成后,可以形成知识沉淀,为软件组织的长期发展贡献力量。这是一个优秀的软件应该要能够做到的。
回页首
软件质量框架的组成
软件质量框架不是理论,而是优秀软件开发思想的一个应用,是对软件开发过程的有效管理实践。它以敏捷方法论为基础,并将先进的软件开发技术融入其中。您可能在之前听说过,学习过,尝试过各种软件技术,但是缺少一个统一整体的认识。所以,软件质量框架的目的是将您原先在脑海中就存在的思路进一步的整理,将一副完整的图像(big picture)展现在你面前。软件质量框架偏重应用,所以不会涉及太多的理论,但是,它是基于理论的,所以,在需要理论支持的地方,我们会简单的描述理论,并给出必要的链接,供有兴趣的读者进一步阅读。
软件质量框架并不复杂,它由几个部分组成,第一部分是前提,说明了软件框架的适用范围,以及适合的环境,和方法学一样,没有泛之四海皆准的方法学,所以软件质量框架也需要一个上下文环境。第二部分是价值观,价值观说明了软件质量框架中强调的价值,在软件框架的结构和实践中,都将充分的的表现出一开始我们定义的价值。第三部分是结构。结构定义了软件质量框架的组成部分,以及软件质量框架和开发过程之间的关系。第四部分是文章中着墨最多的部分,即优秀实践。优秀实践通过具体、实际的分析、举例,深入阐述了软件质量框架的价值观和结构。
在本文剩下的篇幅中,将会对前三个部分进行阐述,并对软件质量开发的实践进行简单的描述。在剩余的篇章中,将会针对这些实践进行细致的分析。
回页首
软件质量框架的前提
平台前提:由于软件质量框架的实践将会涉及具体的技术和代码,所以我们首先为软件质量框架定义了平台。软件质量框架将会运行在J2EE平台上,使用对象分析技术(并不一定是面向对象技术,我们可以采用以数据为中心的技术)。
组织前提:执行软件质量框架需要投入,需要付出,软件质量框架最难的地方不是学习,而是执行。在一个组织中,需要评估应用软件质量框架需要多少的投入,对目前的开发过程有多大的助益。一般来说,组织的规模越大、其开发过程和产品越复杂,就越适合采用软件质量框架。
方法学前提:在敏捷方法学中,对规则和秩序有两种不同的观点,一种是强调规则和秩序,以XP为代表,它对代码都有要求;另一种则不那么强调,以自适应软件开发为代表,它不要求程序员的具体行为。软件质量框架采用第一种观点,要求组织中存在严谨的规则和秩序。
回页首
软件质量框架的价值观
明确具体:对软件的管理必须是明确具体的。软件开发是工程、也是艺术,需要紧密的协作和沟通,任何一个含糊的指令都可能导致软件开发中出现错误,所以,在软件开发中,任何一个指令都应该是相对明确的。为什么说是相对呢?是和成本相对,指令越明确,成本就越高。例如,你可以把需求文档写的非常的具体,但是你需要付出制作和维护的代价。所以我们的明确性是一个考虑成本前提下的特性。
明确具体要从综合上考量。怎么理解呢?例如,XP中的用户故事是非常不精确的,按道理说它是不明确,也是不具体的。但是在整个开发周期中,将会有迭代、测试、现场用户等多种手段使得用户故事明确具体起来,所以从整体上看,它并不违反我们的价值观。产品质量是一个系统工程,决不仅仅是QA部门的工作,。这个道理适用于制造业,也适用于软件开发业。
容错:软件开发是人的工作,人是无法避免错误的。所以,软件质量框架中允许犯错。因为不犯错是天方夜谭。你就算做了这方面的强制规定也无法避免它的出现,反而会引发其它的问题,例如隐瞒错误,或为了隐瞒错误而导致的额外成本。所以正确的态度是允许发生错误,并建立一套监测、管理、反馈、修改错误的体制。
规范:在前提中,我们已经提到了,规范是软件质量框架的基本态度。所以,软件质量框架中强调规范,并使用规范来推动框架的运作。
测试:软件质量框架非常强调测试,测试是保证质量的必由之路。测试要尽可能的多,尽可能的频繁、测试结果要尽可能快的反馈。这是软件质量框架对测试的基本态度。测试是综合性的,软件开发过程中的所有工件,都需要伴随着相应的测试工件。这是基于一个简单的理念,如果你不能够为你的工作制定一个完成的标准,你又该如何开展你的工作呢?
回页首
软件质量框架的结构
上图表现了软件质量框架的结构。处于结构核心的是技术架构和管理架构。软件质量框架既不是方法学,也不是一个软件,更像是两者的结合体。技术架构和管理架构的融合体现了这一特性。软件质量框架并不关心单个开发人员的效率,它关注的是开发团队整体的效率。因此,管理架构在框架中的意义在于它定义了一套软件管理的方法,能够对开发人员及其他们的工作进行管理。从这一点来看,它的作用和软件工程方法学是一样的。但是,在现实中我们发现软件组织在迈向软件过程的途中往往因为现实的困难而止步不前。其中一个主要的原因是在引入方法学的过程中生产效率降低了,而引起组织成员对变革的怀疑和不满。
所以,除了管理架构之外,软件质量框架还提供了一个技术架构,其目的是明确的定义如何应用组织中涉及的软件技术,以及管理软件技术的方法。技术架构是具体的代码,相比起方法学来说,它更加的具体,更容易为开发人员所理解。而技术架构存在的目的,一方面是进行技术积累,另一方面也是为管理架构服务。
技术架构和管理架构的下一层是支撑框架。支撑框架包括代码、组件、文档,目的是为技术架构和管理架构提供底层的支持。
处于结构最顶层的是业务架构。这个部分对于任何一个软件组织来说都是不同的,因为不同的软件组织的业务不同。业务架构的目的是对业务进行建模和抽象,提取出可重用的部分,以提高软件组织的生产率。本文中不涉及该部分的内容。
回页首
软件质量框架的优秀实践
一个开发团队要提高效率,就需要思考目前的管理活动中有哪些要素是可以改进的:如何把一些事务性的操作变得自动化,从而节约人力;如何找到更好的方法,让开发过程更为合理,更注重软件的质量;如何在团队中传播优秀的思想,让团队成员不断的学习和进取,自发的改进过程。这些美好的愿望几乎是所有方法论和各种认证的共同心声,但要完全做到可就太难了。在我们的文章中,提出了一些优秀的实践,优秀实践均是来源于软件开发界中的一些新思路和新理论,它们能够为以上愿望的达成起到正面的作用。在组织中引入用这些实践决不是一个容易的过程,但它们确实非常的有效。不论是在成本控制上,还是在质量的改进上。
日创建:一个组织应当拥有一个有效的工作流程,这个工作流程能够指导软件开发的进行。这个流程应当是具体的、可操作的。随意的计划和从来不遵循的进度决不是一个有效的工作流程。日创建实践提出了一种对开发过程进行精细管理的方法,它是量化软件管理的基础。有了日创建,你会发现计划的制定和进度的监控是非常容易的一件事情。
测试驱动开发:软件质量的根源来源于测试,测试做好了,软件质量就会好。这是毫无疑问的。问题的关键在于怎么做测试,才能保证测试的投入能够带来软件质量的有效提升。测试驱动开发正是为了解决这个问题而出现的。它不是一个完整的方法论,可以和任何一种开发流程进行融合。测试驱动开发不但能够改善测试效果,还能够改进软件的设计。
建立核心框架:框架是一种具有高度重用性的软件,这个特性决定了它非常适合成为软件组织积累知识的一种有效手段。传统的知识积累的方法是文档,但是文档容易产生歧异,开发人员往往也不愿意去阅读和理解文档。框架提供的是一种综合的手段,包括文档、模型和代码。更容易理解,更重要的是,开发人员必须在日常的工作中使用框架,这使得他们对框架中的知识非常的熟悉,并根据工作的需要来改进框架。
面向组件编程:有效的组织在于有效的分工。体力活动容易进行分工,脑力劳动则比较难,而软件开发似乎就更难了。所以,长久以来我们都习惯采用以功能块为单位的粗粒度划分方式。面向组件编程采用更加细密的划分方式,并以服务作为组件之间相互依赖的契约,不但定义了组件和组件之间的关系,也规定了组件开发者、组件使用者、组件测试者的权利和义务。从而能够进行软件开发工作的分配、管理、QA等工作。
以上的几个优秀实践看起来似乎并没有多大的关系,他们的提出者也大都不同。但是有一点却是共同的,就是他们都能够对软件质量的改进起积极的作用。此外,他们为软件质量框架结构的实现提供了一个明确的实现方式。从软件结构的角度来看,日创建和测试驱动开发似乎偏向于管理架构,而建立核心框架和面向组件编程则偏向于技术架构。事实上,他们既包含了技术架构,也包含管理架构,彼此之间也有相互关联。例如,面向组件编程在合理划分组件之后,就需要一个有效的核心框架来集成组件,通过每个组件都需要采用测试驱动开发方法来保证质量,同时,日创建将会以组件为单位来进行每日的创建,从而为进度估算提供有效数据。
随着软件设计技术的发展,新的实践将会出现,取代旧的实践。因此,以上的实践也会落伍,当可以肯定的是,以上的实践和具体的技术并没有直接的关系,更侧重于开发思想,因此他们的生命力会很长。而随着新技术的出现,他们更可能将新的技术融合如自身,呈现出一种崭新的形态。例如,未来的一种可能性是UML2.0和MDA技术的普及,以上的几个实践从以代码为核心转变为以设计为核心,而另一种可能性是随着以AspectJ为代表的AOP技术的普及和J2SE1.5中引入的元数据机制,面向组件编程将把Aspect作为组件的一种,而测试驱动开发也会加入测试Aspect的相关内容,在日创建中也会增加相应的处理AOP的步骤。
在接下来的几篇文章中,我们就针对这几项实践来进行深入的分析。
软件质量之路(2): 日构建
林星 (iamlinx@)
XML error: Please enter a value for the author element's jobtitle attribute, or the company-name element, or both.
林星,致力于研究敏捷理论和优秀的软件设计思想,并将之应用于国内的软件组织。可以通过 iamlinx@和他联系,也可以通过访问 来获得更多的信息。
简介: 日构建是一项非常基础的软件开发实践,遗憾的是,并没有多少组织真正意识到它的好处。通过本章的讨论,你可以知道日构建对软件开发的意义,了解日构建的基本情况以及如何着手进行日构建。
标记本文!
发布日期: 2004 年 3 月 01 日
级别: 初级
访问情况 112 次浏览
建议: 0 (添加评论)
平均分 (共 0 个评分 )
什么是软件开发的有效管理
在一个全国性的银行中,是什么保证复杂的资金清算的正确性的呢?每天,各个地方的网点在结束营业之前,需要保证账目、资金、票据的平衡;这些网点的数据不断的汇集,在每一个汇集点上都要保证账目余额的平衡,最终完成一个银行的一天的结算。天天如此,就像是一部设计精巧的机器一样运作不息。不仅银行是这样,任何一个企业都是如此。一个小杂货铺的老板,也知道每天算算账,看看今天是赚是赔。这些行为已经成为了工作的一部分,甚至成为了一种习惯。
软件开发也是一样的,必须找到一种方法,来衡量每天的工作,保证每天的工作能够有效的持续下去,最终把软件开发的过程变成一种内在的过程。这种方法就称为日构建或是持续集成。
回页首
为什么需要日构建
日构建和持续集成是类似的,对开放源码熟悉的人应该都知道Nightly Build。而持续集成这个词来自XP方法,它的频率可以比日构建更高,可以做到几分钟就进行一次集成,故而由此得名。在本文中,我们只讨论日构建,而要将日构建转换为持续集成是非常容易的。事实上,并没有规定持续集成必须是以分钟为单位进行的,如果你愿意,以一周为单位进行持续集成也是可行的。这样区分的目的是为了更好的使用日构建或是持续集成技术:至少以天为单位,频率越高,效果则越好。
那么,什么是日构建呢?我们传统开发软件的流程一般是这样,理解领域问题,然后分配任务,由不同的人负责不同的软件部件,在开发完成之后,再把各人的部件整合起来,形成完整的软件。这个思路看起来并没有什么问题,但是在实践中却问题多多。
首先,这种方式适合开发人员之间工作彼此没有交集的情况,以前这种现象很常见,但是现在,随着软件规模的扩大、分工合作的加深,开发人员间的相互依赖程度越来越高,这种清晰的职责划分已经变得越来越难了。
其次,在软件集成时,往往会出现各种各样的问题,可是却很难发现到底问题在哪里?公说公有理,婆说婆有理。每个人的代码都没有问题,结合到一起就出现大量的问题。
所以日构建就将平时难得一见的集成工作转换成频繁进行的一件工作,从而使得原先如同噩梦般的集成变成了一件简单的工作。这也是很容易理解的,如果集成工作几个月才进行一次,谁能够记起几个月前的细节呢?但是如果集成以天,甚至以分钟为单位进行,排除bug就变成一件很容易的事情了。
回页首
日构建范例
现在的时间是下午的17:00,马上就到日构建的时间了。团队里四名程序员中的三位已经将自己的源代码和测试代码提交到了一台名为宙斯的机器上,这台机器将负责对代码进行日构建。在他们提交代码之前,已经通过了本机上的构建,并完成了测试。剩下的一位程序员似乎碰到了麻烦,他的代码出现了一些问题,他现在需要编写更多的测试来完善测试网。看来时间来不及了,他只能够在明天再做提交了。由于他的代码没有和其他人产生依赖,所以迟些提交也没有关系,不过他在下个工作日的时候必须仔细的将最新的源代码检出到本地,在版本控制工具的帮助下,这项工作是很简单的。
17:10,宙斯终于开始了构建的过程。他从代码源中检出最新代码,然后开始编译,构建,并执行了所有的测试,从控制台界面上,日构建的负责人(其中的一位程序员)似乎看到了有部分的测试没有通过,他对剩下的人说,似乎有麻烦了。测试完成之后,将会从代码中生成所有的API文档,并进行代码分析和测试覆盖率分析,最新测试报告和各种其它的报告都将会发布到Web上。
最后。完成构建的软件和相关的资料已经成功的发布了,时钟指向17:18。"现在只是项目的早期,到了中后期,至少还需要20分钟的时间",老鸟程序员告诉没有经验的程序员,并让大家去看看测试结果。一个程序员边嘟囔,边看log日志,"我在本机都已经测试过了呀,怎么会有错呢。"检查结果发现是环境问题,配置文件被人改动了。看来,集成过程中仍然少不了冲突的问题,只不过,这些问题可以被很快的发现,并很快的得以解决。
以上是一个典型的日构建过程,日构建的过程是完全自动化的,通过预先定义好的指令,机器将按照指令顺序执行完所有的构建步骤。日构建中涉及的步骤是可选的。
回页首
日构建的价值
可能有些人认为日构建过于浪费时间,但是实际上,比起最后除错的成本来说,日构建成本是微不足道的。当然,在企业中建立日构建制度确实需要花费不少的时间,但从长远来看,这绝对是值得的。
从表面上看,日构建能够减少最终的排错成本,但这仅仅是日构建最基本的价值。实际上,日构建更为关键的作用是能够引入日构建的制度。这是什么意思呢?日构建的思路将会为软件企业的开发流程带来变化:开发人员将会在日构建的制度下更加频繁的协作,开发进度一目了然,软件的质量也会更加的稳定。
软件开发本身就是一项强调沟通和协作的活动。但是在日常的活动中,常常出现阻碍沟通的情况,例如需要沟通的双方不在同一个地理位置、噪声、沟通双方的意愿等等。因此在软件管理中需要提供一种方法,来鼓励人们进行沟通。日构建就是其中的一种方法(但它并不是唯一的方法)。每一次的构建将会涉及到团队中的所有成员,因此沟通是少不了的,在日构建实践的驱动下,每位开发人员都朝着最终的目的-"成功的构建"努力。
在Alistair Cockburn的敏捷软件开发的第三章中,详细的阐述了团队沟通和协作中的相关问题。例如沟通的实质,影响沟通的各种因素,以及如何克服他们。最后,他还论述了如何促进团队的沟通,来打造一支成功的团队。
在日构建的驱动下,项目的进度将会变得非常的明显。每一天的构建结果将会通过某个渠道发布出来,团队和团队的老板可以看到软件现在的样子,项目的完成情况,出现的问题等等。这些信息构成了软件开发的基本信息。不但可以清晰地描述出项目进度,也为管理人员安排计划提供了基础数据的支持。有了基本的量化数据,软件开发才不是靠拍脑袋出成果的。
日构建的最后一个价值是提供了整合性。目前软件开发中并没有一种统一的管理软件,未来似乎也很难做到,因为不同的软件组织差异很大。在开发过程中,一些有价值的实践被加入、集成到日构建的过程中,在日构建的推动下,这些优秀实践很容易成为开发过程的一部分。在文章倡导的另一个优秀实践-测试驱动开发实践,就很容易集成到日构建中来。事实上,软件测试是非常重要的,它已经成为日构建成功的判别因素。
回页首
选择日构建还是持续集成
虽然日构建和持续集成的本质是相同的,但是他们在集成的频率方面的差异也导致了一些管理上的差异:
首先,日构建树立了一个明确的以工作日为单位的小目标,团队的目的就是为了使代码能够通过每天的构建。开发人员在明确的目标的指导下,往往能够发挥出很高的效率。持续集成则将这个频率变得更小,只要你的代码提交到代码库中,立刻就会检验你的成果,如果有问题,你必须立刻排除,否则,要么集成的过程无法继续,要么出错的开发人员的信箱被集成过程中的警告信息所填满。这种做法对团队的要求要更高一些。对于刚刚开始接触日构建的团队来说,可能会手忙脚乱。
其次,日构建有一条非常明确的分界线,开发工作要么是完成,要么是没有完成,不存在第三种状态。
回页首
日构建的基础实践
日构建的基础包括三个实践:自动构建、统一代码源和集成测试。
自动构建
自动构建的思路是通过脚本语言,而不是通过在IDE环境中点击构建按钮来完成项目的构建过程。日构建需要不断的进行集成的工作,如果手工来完成这项工作,既费时,效果又不好。所以更聪明的做法是把这件工作给自动化。在早期的Unix环境中,都是采用Make编写相应的脚本来完成构建的过程。随着先进的IDE环境的发展,慢慢的人们就不愿意再编写Make脚本了。可是现在,为了自动构建的目标,我们需要回归到手工编写Make脚本的历史上去。应该说,IDE环境中的构建方式侧重于个人开发,而自动构建则侧重于团队开发
自动构建目标就是通过一个简单的命令就能够全部的构建过程。
统一代码源
其次,保证一个开发团队共享统一的代码源。这时候我们需要使用版本控制工具。共享的代码库同样也是XP的一个基本实践。虽然XP还要求开发人员可以修改他人的代码,但我们并不提倡这种做法,这要求团队成员之间有非常高的默契程度。统一的代码源能够保证所有人的代码都归总到一起,这是日构建的基础。如果没有这一点的保证,每一次的构建我们都不得不把所有人的代码集中起来,这无疑会使构建过程变成灾难。
统一代码源能够保证任何一位团队成员获得所有的代码,并以此为基础进行开发。
集成测试
只是把代码编译通过并不能够证明软件可以正常工作,评价软件的标准应该是测试。在日构建中必须要执行集成测试,来保证软件确实是能够工作的。
集成测试也是一个同义词相当多的名词,有人把它称为验证测试(BVT-Build Verification Tests),因为他们认为这种测试主要的目的是为了验证构建的正确性。有些人把它称为冒烟测试(Smoke Test),因为他们觉得这个测试的目的是运行软件,看它是否会"冒烟"。
测试应该全部执行完毕,而不是遇到未被满足的错误就放弃测试过程。测试将形成结果,成功的测试,失败的测试,失败测试的细节。最后的结果将通过某种方式通知给相应的人员,要求他们修改设计或测试(如果是测试本身的问题的话)。
集成测试是证明构建成功的关键因素。和构建一样,集成测试也应该是自动化的。
回页首
日构建的基本工具
日构建的工具有很多,但是最基础、最广泛的工具是Ant(http://ant.apache.org)。Ant类似于Make,但是加入了跨平台的特性。在这个目标的驱动下,Ant摒弃了Make工具的给予Shell的缺点,提供了一种使用XML配置文件的构建方式,并定义了一个统一的微核心和强大的扩展机制。这些特点使得Ant很快被人所接受、推广。目前,Ant的最新版本是1.6.0。
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean" description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
以上是一个简单,但已经可以完全说明Ant工作流程的例子,来源于Ant的手册。在这个例子中,先定义了项目的基本信息和构建过程中所需要使用到的属性(1),然后初始化环境(2)(创建时戳和目标目录),在3和4中,对项目进行编译和打包,在5处,提供了清除项目输出的途径。
在Ant中,最关键的四个概念就是项目(Project)、目标(Target)、任务(Task)和属性(Property)。这四个概念的定义和调度、配置文件的处理构成了Ant的核心。而具体的任务则作为扩展机制。这种微核心的处理思路在很多成功的软件项目中采用过。
本文并没有打算对Ant进行全面的介绍,因此,如果你打算在组织中引入日构建,那么,学会使用Ant是必须的。目前很多的IDE环境都提供了对Ant的支持(例如Eclipse),所以使用Ant是很方便的。
原则上,光有Ant就已经可以完成一个日构建过程了,但是还有一些软件提供了更好的封装,使得持续集成变得更加的简单。典型的两个工具是AntHill( Folwer所在的ThoughtWorks公司开发的,可以免费使用。
另一个值得关注的软件是Apcache组织下的Maven项目( http://maven.apache.org/)。这个项目还很年轻,目前才到1.0的发布版。Maven给自己的定位是项目管理软件,使用项目对象模型(POM)来描述一个项目,进一步的简化构建过程,并统一构建过程所出产的工件。Maven的另一个目标是通过一种实际的工具,来推广优秀的实践。例如开发目录树的组织。
回页首
日构建的代价
虽然日构建有诸多的好处,但是要使用日构建并不是一帆风顺的。最大的问题是如何引入日构建的三项基本实践。前两项相对简单,最难的是建立自动化测试。关于这部分的说明请参考测试驱动开发的相关部分。
回页首
日构建扩展任务
日构建的核心任务是编译、构建、执行测试和发布。除了这些任务之外,还可以微日构建添加扩展任务。
生成文档。生成文档有很多的方法,其中最关键的是生成API文档。JavaDoc的概念减弱了传统软件开发中文档的重要性,而把大量的文档嵌入到了代码层面中。除了标准的JavaDoc文档之外,还可以利用第三方的工具生成自定义的文档,例如to-do列表文档。XDoclet就是其中的一个工具。
预编译。不少的应用引入了预编译。典型的如AspectJ,作为一个AOP工具,AspectJ的作用是使用特定的代码生成器生成AOP的Java代码,然后再进行编译。将预编译的工作纳入到构建过程,可以简化开发的工作量。典型的还包括一些ORM工具。
代码分析。代码分析是软件度量的重要工作。代码分析可以为管理人员提供一个判断代码质量依据(不要把它作为唯一的标准)。代码分析是形式化的,因此可以制作成软件,集成到构建过程中来。例如,判断代码是否符合编码规范,文档和代码的比率,包和类涉及的合理性。
测试覆盖分析。测试覆盖分析作为辅助测试的手段是非常重要的。测试代码的复审,最关键的评价测试是否足够(相对),单靠人工完成这项工作太勉强了。所以应该令其自动化,并成为构建过程的一部分。
问题跟踪。测试过程中出现的问题应该被纳入到一个问题跟踪系统中,可以通过和问题跟踪系统接口来设计自动化的任务。
归档和备份。这是很基本,但也是很重要的功能。每天产生的工件应当进行妥当的归档、备份。
回页首
进一步了解
试图在短短的一篇文章中完整介绍日构建技术是很难的,从DW的网站上,你可以找到更多管理日构建工具的相关内容。
关于作者
林星,致力于研究敏捷理论和优秀的软件设计思想,并将之应用于国内的软件组织。可以通过 iamlinx@和他联系,也可以通过访问 来获得更多的信息。
软件质量之路(3): 测试驱动开发
林星 (iamlinx@), 致力于研究敏捷理论和优秀的软件设计思想
林星,致力于研究敏捷理论和优秀的软件设计思想,并将之应用于国内的软件组织。可以通过 iamlinx@和他联系,也可以通过访问和www. aglichina.org来获得更多的信息。
简介: 测试不能够证明错误不存在,只能够证明错误存在。尽可能测试一切可以测试的东西。
标记本文!
发布日期: 2004 年 3 月 01 日
级别: 初级
访问情况 124 次浏览
建议: 0 (添加评论)
平均分 (共 0 个评分 )
测试是如何驱动开发过程的
测试驱动开发起源于XP法中提倡的测试优先实践。测试优先实践重视单元测试,强调程序员除了编写代码,还应该编写单元测试代码。在开发的顺序上,它改变了以往先编写代码,再编写测试的过程,而采用先编写测试,再编写代码来满足测试的方法。这种方法在实际中能够起到非常好的效果,使得测试工作不仅仅是单纯的测试,而成为设计的一部分。为什么这么说呢?
在编写程序之前,每个人都会先进行设计的工作。可能有些人的设计比较正式,绘制模型,编写文档。有些人的设计只是存在于脑海之中。且不论是设计是精细还是粗糙,你都为随后的编码活动制定了一个标准。这个标准的明确程度和你的设计的细致程度有关。但应该承认,这个标准是不够细化的。因为你的设计不可能精细到代码级的程度。而标准不够明确的则会产生一些问题,例如,在编写代码的过程中,你还可能会发现原先的设计出现问题,从而中途改变代码的编写思路。这将会导致成果难以检验,进度难以度量。
既然以设计为导向的标准不够明确,不够具体。那什么样的标准才是合适的呢?只能是代码。因为代码是最明确、最具体的。所以测试优先的本质其实是目标管理。编写测试代码其实是在制定一个小目标。这个小目标非常的明确,它规定了你需要设计的类、方法。以及方法需要满足的结果。这些目标制定完成之后,你才开始编写代码来达成该目标。测试的目标要比设计的目标粒度更小,但是成本上却更为经济。其原因有四:
· 细粒度的设计需要花费大量的成本,虽然CASE工具都提供了代码自动生成的功能,但结果往往难以令人满意。所以,设计如果要做到和测试相同的粒度,成本不菲,如果粒度不够细,指导的意义又不够。
· 减轻了测试的工作量。无论是否进行设计工作,测试工作都是不可避免的,先进行单元测试,可以减少后续的测试工作量。
· 采用测试优先的过程中,设计的粒度较大。因为测试可以实现一部分的设计工作。这样,设计上可以节省一些工作量。例如,你不再需要将类图细化到每个方法。
· 在编写测试代码上花费的成本,会在回归测试上得到回报。自动化测试的最大好处就是避免代码出现回归。两相权衡,编写测试的代价其实不高。
你也许会说,我既不进行如此精细的设计,也不事先编写测试代码,这样的成本不是最低吗?请注意,我们的前提是在讨论高质量的软件设计。在一些规模较小或是开发人员能力极强的项目中,确实可以如此办理。但是对于强调质量的大项目,这种处于混沌状态的开发思路是不可取的。
测试优先是软件开发中一种细粒度的目标管理方法,通过明确的目标,推动软件开发的进行。
在业界中,采用测试作为评价软件标准的做法是非常常见的。例如,sun公司就专门设计了测试软件,对各个实现J2EE规范的产品进行测试。使用测试作为规范的最大好处就是明确、具体。
使用测试代码建立目标,编写代码完成测试目标,再制定下一个目标,如此循环,构成了测试驱动开发的工作流程。在接下去的篇幅中,我们开始讨论测试驱动开发中需要注意的一些问题。
回页首
测试必须是自动化的
和自动化测试相对的是手动测试。手动测试有着自动化测试所没有的优势。最明显的就是简单。任何一位开发人员都能够进行手动测试。即便是用户,也很容易掌握手动测试,他们输入数据,并观察软件的反应(输出),从而判断行为是否正确。大部分的手动测试都是对输入和输出的检验,是一个端到端过程,很能说明问题。
但是手动测试存在的问题比它所带来的好处要多得多。手动测试可能引入错误,人为的输入错误很容易发生,尤其在数据量大的情况下;大量重复性的手动测试可能成本较高,如果考虑软件发生改动而需要重复手动测试的情况,这个成本还会更高;手动测试的覆盖面不广,只能够测试系统的输入和输出;没有办法对组件进行隔离的测试,从而导致发现问题和解决问题的成本都太高。
基于上面的讨论,我们应该看到,测试应该做到自动化。虽然一开始测试自动化的成本较高,但是从整个的开发过程来看,自动化测试所产生的价值远远超过其成本。
回页首
自动化测试的范围
那么,到底有哪些东西是需要纳入到自动化测试的范围的呢?例如,对于一个典型的分层应用来说,就有数据库层、数据库访问层,业务逻辑层、界面控制层、界面层。这些层次的测试特点各不相同,哪些应该进行自动化测试呢?最理想的情况是全部。测试一切可能是测试的基本原则,让一切测试都变成自动化则是测试驱动开发的准则。
应该承认,建立自动化测试需要付出成本,有些自动化测试成本较低,有些则较高。例如,对业务方法的自动化测试相对容易,对关联到数据库的业务方法的测试则繁琐一些,因为你需要处理更多的情况。而界面的自动化测试则较困难,因为界面涉及到大量的人机交互,手
展开阅读全文