(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf_第1页
(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf_第2页
(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf_第3页
(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf_第4页
(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf_第5页
已阅读5页,还剩55页未读 继续免费阅读

(计算机软件与理论专业论文)基于测试驱动开发的tjul语言实现研究.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要 现今社会,随着信息技术的不断发展,人们对软件质量的要求越来越高。如 何在需求不断变化的环境中开发出高可靠性、高质量的软件系统已成为软件行业 日益关注的问题。软件测试是保障软件质量的关键,但开发者通常都是先写代码 后测试,而且当时间很紧迫时,测试就变得很困难且经常被忽略。 近年来,一种新型的面向对象开发实践一测试驱动开发的提出,将测试工 作提高到一个新的高度。它强调编码之前先写测试用例,通过持续重构,使代码 更加精炼,最终获得瑕疵率极低的程序系统。 本文先深入研究测试驱动开发t d d 的特点以及它对软件开发各阶段的影响, 剖析t d d 与传统软件开发模型和测试方法的异同。然后结合实际,阐述了测试驱 动开发在天大语言t j u l 实现中的应用。基于t d d 实现图形用户界面的难点及特殊 性,本文采用模拟测试驱动实现。最后从测试度和度量代码两方面评估此次t d d 实践效果。为更客观的反映代码设计结构,对面向对象度量方法c & k 中的某些度 量参数做了改进。从评估效果看,整体上达到了各项度量参数标准并且测试充分 而不过度。由于t d d 本身的局限性,提倡t d d 与传统的开发思想、设计模式等相结 合的软件开发方式,以取长补短,做到既能发挥t d d 的优势,又能让开发者更容 易接受。 关键词:测试驱动开发极限编程编译重构 a b s t r a c t n o w a d a y s ,h o wt od e v e l o ph i g h l yr e l i a b l ea n dq u a l i f i e ds o f t w a r es y s t e mh a s b e c o m ead a i l yc o n c e m t e s t i n gi st h ek e yt og u a r a n t e e i n gs o f t w a r eq u a l i t y , b u t d e v e l o p e r su s u a l l yw r i t ec o d eb e f o r et e s t i n g w h a t sw o r s e ,t e s t i n gi sf r e q u e n t l y n e g l e c t e dw h e nt i m ei su r g e n t r e c e n t l y ,an e wk i n do fo b j e c t - o r i e n t e ds o f t w a r ed e v e l o p m e n t t e s t - d r i v e n d e v e l o p m e n th a sb e e np r o p o s e d i te n h a n c e st e s t i n gt oan e wa l t i t u d e i te m p h a s i z e s w r i t i n gt e s tc o d e sf i r s t ,t h r o u g hc o n t i n u a lr e f a c t o r i n g ,w ef i n a l l yg e tr e f i n e dc o d ea n d s l i g h tl o 、v 一- d e f e c t e dr a t eo fs o f t w a r es y s t e m f i r s t ,t h i sp a p e rs t u d i e sf u r t h e rt h et h e o r yo ft e s t - d r i v e nd e v e l o p m e n t t h e n ,w e p u t i ti n t op r a c t i c ei nt j u lp r o g r a m m i n gl a n g u a g ei m p l e m e n t a t i o n 。g i v e nt h e d i f f i c u l t i e so fg u ii m p l e m e n t a t i o nu s i n gt d d ,t h i sp a p e ra d o p t sam e t h o dn a m e d s i m u l a t e d - t e s tt oc o n s t r u c tg u i a tt h ee n d ,t ob e t t e ra s s e s sc o d e ss t r u c t u r e , w e m a k ef u r t h e ri m p r o v e m e n to ns o m ec & km e t r i c sp a r a m e t e r st oa p p r a i s et h ee f f e c to f t h i sp r a c t i c ef r o mt e s tc o v e r a g ea n dc o d eq u a l i t ym e a s u r ea s p e c t s f r o mt h er e s u l t s ,i t l i v e du pw i t hm o s to fm e a s u r ep a r a m e t e r s s t a n d a r d b e c a u s et d dh a si t so w n l i m i t a t i o n s ,w ea d v o c a t eac o m b i n a t i o no ft d da n dt r a d i t i o n a ld e s i g np a t t e mt o a c h i e v et h ea d v a n a t a g e so ft d da n dl e td e v e l o p e r sa c c e p ti tm o r ee a s i l y k e yw o r d s :t e s t - d r i v e nd e v e l o p m e n t , e x t r e m ep r o g r a m m i n g ,c o m p i l e , r e f a c t o r i n g 独创性声明 本人声明所呈交的学位论文是本人在导师指导下进行的研究工作和取得的 研究成果,除了文中特别加以标注和致谢之处外,论文中不包含其他人已经发表 或撰写过的研究成果,也不包含为获得丞注盘堂或其他教育机构的学位或证 书而使用过的材料。与我一同工作的同志对本研究所做的任何贡献均已在论文中 作了明确的说明并表示了谢意。 学位论文拓者签名:玄、j 冠橱签字日期:。口0 1 年月f r 日 学位论文版权使用授权书 本学位论文作者完全了解基鲞盘堂有关保留、使用学位论文的规定。 特授权丕鲞盘鲎可以将学位论文的全部或部分内容编入有关数据库进行检 索,并采用影印、缩印或扫描等复制手段保存、汇编以供查阅和借阅。同意学校 向国家有关部门或机构送交论文的复印件和磁盘。 ( 保密的学位论文在解密后适用本授权说明) 学位论文作者签名:文- l 钮梅 签字日期:0 口刁年 月扩e l 聊签礞巨灰 辩醐:叼年莎月驴 第一章绪论 1 1 研究背景 第一章绪论 现今社会,快速变化和多样性已成为时代的特点。人们寻求各种途径来保证 软件的质量,其中一种就是强调增强设计。适当的前期设计可以有效地提高软件 质量,但由于软件本身的复杂性、用户需求不断变化的本质就决定了设计并不能 以很高的概率来保证软件质量。 传统软件工程如瀑布模型强调早期详细计划和需求调查,认为通过早期确定 所有的需求就可减少后期需求变动而引发的成本增加,它总是努力把变动排除在 开发进程之外。但事实上,在今天这个飞速发展的世界中,外部环境( 需求、范 围、技术) 是时刻变化的。在项目开始的初期,客户往往很难一次性就完全说清 楚他们想要什么样的系统,这难以避免的变化致使系统一改再改,不能及时交付 甚至最终开发出来的系统根本不能满足客户的需要。如何应对瞬息变化的环境, 开发出高可靠性、高质量的软件系统已成为软件行业日益关注的问题。 近年来,相对于传统的软件工程方法,能更灵敏地对变动做出反应的新一类 软件工程方法敏捷软件开发方法a s d 出现了。它是一种轻量级的软件开发方 法,强调以人为本、积极响应客户需求变化,尽可能少地约束开发人员,充分发 挥开发人员的创造性,以提高软件质量l l j 。 其中极限编程x p 是目前所有敏捷开发方法系列中最受关注、实践最多的一 类方法。它将注意力集中放在提高软件价值的层面上:即对系统的需求以及实现 系统的代码。而作为极限编程x p 重要实践活动之一的测试驱动由于其紧密地反 馈循环而成为一项有效的错误检测和消除技术。 1 2 国内外研究现状及意义 进行充分的软件测试可以有效地提高软件的质量。但遗憾的是,测试往往不 被重视,大部分程序员都认为测试是项目后期的工作,有时甚至怕没时间懒于测 试,从而出现恶性循环:越是没空编写测试程序,代码的效率与质量越差,花在 找b u g 、解决b u g 的时间就越多,效率反而大大降低。效率一低,时间就更紧 张,压力也更大。 第一章绪论 测试驱动开发t d d 的出现,将测试工作提高到一个新的高度测试先于编 码。它作为软件开发的一个重要实践越来越受到关注,实践表明它比较适合中小 型项目的开发。然而关于t d d 的研究及实践大部分集中在德国和美国,在亚洲还 没有盛行开来l z j 。此外,近十年来,软件外包越来越流行,中国己取代印度一跃 成为了日本的最大外包市场。而外包代码的规模一般都不大,最大问题就是如何 保证代码质量和控制开发进度。所以外包软件需要一个更加可靠而有效的开发方 法,来保证代码质量和控制开发进度。 尽管t d d 在国内软件开发行业还没有得到很好的实践和验证,但它至少可 能是一个解决当前问题值得尝试的途径。因此,很有必要在国内进行相关方面的 研究和实践。只有通过大胆的实践才能看清问题的真实面目。本文对比式研究了 极限编程x p 的重要实践活动之一测试驱动开发t d d 的方法特点,并且将 t d d 理论具体应用于t 几几语言实现上,最后对此次实践效果进行多角度的评 估。 1 3 本文研究工作及结构安排 本论文首先深入研究极限编程x p 、测试驱动开发t d d 的相关内容及特点, 然后结合实际,用测试驱动方法具体实践t j u l 语言实现过程。 论文结构安排如下: 第一章引言介绍了本论文提出背景及研究内容和意义; 第二章主要深入研究x p 及测试驱动开发t d d 相关理论,并剖析它们对开发 各阶段的影响及与传统各模型的异同点; 第三章按照t d d 开发步骤,先对t j l i 语言实现过程进行概要设计。 第四章为t d d 具体实践部分,介绍如何采用测试驱动开发方法实现其编译 过程及图形用户界面,并且对实践效果进行评估; 第五章对本文工作进行总结,指出今后进一步的研究工作。 2 第_ 章x p 与t d d 2 1 极限编程x p 第二章x p 与t d d 敏捷软件开发a s d 是一种相对传统软件开发而言的快速响应需求变化的轻量 级开发方法。它是以人为本、把满足用户需求作为目标,尽可能少地约束开发人 员,充分发挥开发人员的创造性,以提高软件质量1 1 】。它是一系列方法的统称, 其中极限编程e x t r e m ep r o g r a m m i n g ( x p ) 是目前最受关注、实践最多的一类敏捷 方法。k e n tb e c k 于1 9 9 6 年春为c h r y s l e r 公司开发一个c 3 薪水付账工程项目时第 一次使用x p 方法进行实践1 4 j 【5 j 。x p 是k e n tb e c k 与w a l dc u n n i n e h a m 在2 0 世纪8 0 年 代末期共同合作的研究结果。 极限编程是一套能快速开发高质量软件所需的价值观、原则和活动的集合, 以沟通、简单、反馈、勇气为核心价值,将注意力集中放在提高软件价值的东西 层面:对系统的需求以及实现系统的代码【6 儿7 。目标就是能够在最短的时间内, 把较为模糊的、变化幅度大的需求变为软件产品。 2 1 1x p 的动态柔性设计 在一个长期项目中,检验一个系统是否具有很好的柔性是看原设计能否很容 易的实现新变化需求。传统“先设计,再维护”的策略,它的最大问题在于:随 着时间的推移,维护、改错、打补丁、增强功能等工作会使系统的熵越来越大, 外部环境变化加快,情况越来越糟。如图2 - 1 所示: 基于适应的过程 图2 1 预先设计与动态设计 的结果 的结果 从图2 1 中可以看到:辛辛苦苦努力工作实现其最初的设计目的,但事实上, 第_ 章x p 与t d d 它早已背离其实际需要很远了。从软件发布之口起,它就已经过时,已经需要完 善了。完善的过程同样有需求的进一步变动。软件设计就是在这种你跑我追的情 况下,达到最终用户可以接受的结果。若采用x p 的动态设计,再去处理这些变 更的风险,就大不相同了。如图中曲线所示,x p 以动态适应性代替传统预测性, 它不主张在设计之初就全面考虑系统的灵活、柔性解决方案,而是通过一次次的 迭代,来修改系统那些不满足用户新需求的部分。它的开发目标不是系统设计时 所订下的目标,而是系统交付之日的客户要求最贴近于实际的需要。 2 1 2 与传统软件工程对比 传统软件工程t r a d i t i o n a ls o f t w a r ee n g i n e e r i n g ( t s e ) 方法如瀑布模型,强 调开发过程要严格遵守分析、设计、实现和维护的标准文档格式和细节,其生命 周期属于一种线性模型。t s e 通过规则和操作规范的形式约束开发过程来保证软 件的质量和可靠性,以计划驱动思想规范化编程习惯。但过多的规范约束反而会 成为开发人员工作中的一种负担。尤其当面对的项目属于中小型规模系统的时 候,t s e 已不能适应实际开发过程的需要。极限编程模型是一种轻量级的开发方 法模型。与传统方法不同,x p 拥抱需求变化,能够在最短的时间内,把较为模糊 的、变化幅度大的需求变为软件产品。下面从软件开发过程的特点、软件过程、 实践指导规则和适用范围等方面,比较二者的主要差异。如表2 1 所示: 表2 1t s e 与x p 对比 项目 t s ex p 开发队伍构成客户和管理者只在项目初期 客户、管理者、开发者;客户 和最后验收出现,不参与具体参与项目开发的全过程 开发过程 需求分析一次需求分析作为用户实际可能有多次需求分析,以适应 完整、静态的需求用户需求变化 开发过程的核心以需求、规则文档为中心以人为中心 代码编写与调试由单人或多人独立完成结队编程,以模块为单位 对计划的依赖完全计划适当计划而不是完全无计划 系统可重构性非常困难甚至不可能比较容易 适应与变化难以利用反馈信息,不欢迎变以适应为基础,欢迎需求变化 化 发布规模与间隔 大型发布,稀疏发布( 以月或 小型发布,频繁发布( 几周之 年计)内) 适合的软件规模 大型或超大型系统( 几十人以 中小型系统( 2 l o 人) 上) 4 第二章x p 与t d d 从表中可看到,x p 以适当的或够用的文档或标准,通过客户对项目的全程参 与,进行用户可接受式测试、连续集成与频繁发布来反馈与逼近真实的需求,持 续重构完成产品的优化。对比研究结果表明,x p 模型比t s e 模型更适合于中小 型软件系统的开发。 2 2t d d 越早发现错误,修复错误的代价就越小。近年来,随着敏捷软件开发极限编 程的兴旺发展,出现了一个新型的软件开发实践一一测试驱动开发t e s t d r i v e n d e v e l o p m e n t ( 简称t d d ) 。它也称为测试驱动编程、测试先行开发,是由k e n tb e c k 提出的一种软件开发方式,是极限编程的核心技术之一,当然t d d 也可作为独立 的软件实践方法。其具体含义如下1 1 1 j : , 要维护一套详尽的程序员测试集。 除非存在相关测试,否则不编写任何产品代码。 首先编写测试。 由测试来决定需要编写怎样的代码。 2 2 1t d d 开发步骤 t d d 并不是一种测试方法,而是一种程序设计方法。它将单元测试和程序设 计紧密地结合在一起,用单元测试来驱动指导程序设计 1 3 】。整个测试驱动开发过 程可比喻成交通灯( 在自动化测试框架j u n i t 的信号灯) 先黄后红再绿交替显 示1 2 5 1 。其基本步骤如下: ( 1 ) 编写能表明某项待完成功能的测试。 ( 2 ) 运行测试。编译失败( 黄灯) ,因为被调用的函数还没有写。 ( 3 ) 依据编译报错提示信息编写相关应用代码,使所写测试通过编译即可。 ( 4 ) 编译通过,但测试失败( 红灯) 。 ( 5 ) 写程序的主体,使测试可以通过。 ( 6 ) 运行测试,测试通过( 绿灯) 。 ( 7 ) 从藕合性、内聚度、冗余和简洁几方面来重构代码。 ( 8 ) 测试再次通过( 绿灯) 。 ( 9 ) 回到( 1 ) ,直到关于系统其它功能的测试都写完。 以下是t d d 开发的流程图: 第二章x p 与t d d 图2 - 2t d d 基本步骤 2 2 2t d d 对开发过程的影响 这一节将主要分析测试驱动开发对软件开发过程各个阶段( 需求分析、设计、 编码和测试) 的影响。 1 ) 测试驱动开发对需求分析的影响 在软件需求分析阶段,t d d 就引入测试。该阶段测试的重点是如何定义测试 计划、接受测试并获得客户认可。在需求分析结束时,保证所有的需求都是测试 的,均拥有测试用例。另一项重要的测试任务就是建立一个测试环境以及这个软 件项目所需要的测试数据。通过在需求分析阶段引人测试,开发人员可清除各种 矛盾以满足用户需求。 2 ) 测试驱动开发对设计的影响 将需求转换为软件表达式的过程是软件设计阶段的工作。在设计阶段,测试 工作的重点在于如何定义各个模块的详细测试内容,最好的方式是实现测试代码 并构建测试框架。t d d 坚持测试优先的实践,用测试来推进设计。使设计人员 用测试的角度考虑设计,从一个外部接口和客户端的角度考虑问题,这样可保证 系统各模块之间能较好的连接在一起,同时设计人员的思考方式也逐步地从单纯 的考虑实现转移到对软件结构的思考上来。采用测试优先的过程中,设计的粒度 较大( 因为测试可以实现一部分的设计工作) ,这样设计上可以节省一些工作量。 3 ) n 试驱动开发对编码的影响 编码阶段的工作是用编程语言将对设计表达式翻译为机器能够“读懂”的形 6 第二章x p 与t d d 式。t d d 在编码阶段引人测试的目的在于由测试来决定如何编写代码。在代码 编写之前强调测试,可促使开发人员更清楚在程序中应该加入何种性能以及如何 使这些性能良好运作。如果我们能把所有不明确的问题都在写测试的时候首先被 解决,那么就会使之后复杂的编写代码工作变得相对轻松。 4 ) 澳f j 试驱动开发对测试的影响 这里用维恩图表示测试概念。如图2 3 所示,图中的全域表示程序行为,集 合p 是用程序实现的行为,集合s 是用户描述的行为,集合t 是测试用例。s 和 p 相交的部分是“正确”的部分既被描述又被实现的行为。测试就是确定既 被描述又被实现的程序行为的范围。因此我们要使s 、p 和t 的相交区域l 尽可 能地大。在测试驱动开发中,集合s 、p 、t 三者相交关系如图2 4 所示,由于代 码基于测试编写,因此程序集合p 和测试用例集合t 重合,从而实现了代码与 测试的一致性,也保证了程序代码的可测试性和测试覆盖的完备性。 图2 - 3 软件测试维恩图图2 4t d d 测试维恩图 2 3t d d 异于传统测试方法、模型 2 3 1t d d 与传统测试方法的对比 传统的软件测试通常是在完成编码之后由专门的测试人员负责完成。这种滞 后性测试也就导致它存在以下几个问题: 1 ) 测试通常是在所有代码编写完毕后开始的,一旦不再与某程序打交道时, 要折回头处理其中问题势必花费一些时间和精力。同时测试不是由编写 代码的程序员编写会致使测试人员可能不能理解所有代码而漏掉一些重 要的测试。 2 ) 当测试人员编写测试依赖的是文档而不是代码时,如果文档和代码存在 第_ 二章x p 与t d d 任何不一致的地方就会造成问题。 3 ) 如果测试不能自动进行,那么它们极有可能不会被频繁、经常性的运行 或是每次都以相同的方式来运行。 4 ) 传统纠正错误的方法极有可能是在一个地方改正了错误而又在别的地方 出现新的问题。 相比之下,测试驱动开发不仅解决了上述传统测试存在的问题,而且还附带 解决了其它一些问题: 1 ) 测试由程序员完成,在代码在脑海中清晰可见时就对测试进行操作,可 降低理解代码所花费的成本。此外,代码是基于测试编写的,这样保证 代码的可测试性,有助于确保测试覆盖的完备性以及代码与测试的一致 性。 2 ) 全面彻底的测试覆盖意味着如果在系统中增添了新的代码或调试阶段引 入某个“臭虫”,测试集就能立刻发现出错位置。测试一调试周期被控制 在相当短的时间内,从而加快代码开发速度,把更多的时间花在开发代 码而不是测试或调试阶段。 3 ) 所有测试可自动运行的,这样就可频繁地以完全相同的方式运行测试。 4 ) 由于只有正确理解系统需求,才可能编写合适的单元测试用例。在开发 初始阶段,t d d 要求开发人员以测试的角度对软件进行审视,促使他们 更好的理解系统需求,对软件有全面的认识和把握。 5 ) 倡导更简单的设计,编写仅仅满足要求的代码。 6 ) 减轻了测试的工作量。无论是否进行设计工作,测试工作都是不可避免 的,先进行单元测试,可减少后续的测试工作量。 7 ) 最后,当系统发布时,详尽的测试集与其一同发布,从而使得将来对程 序的修改和扩展更加容易。 因此,单从纯测试的观点看,先不谈那些非测试方面的益处,测试驱动开发 要优于传统测试方法。在t d d 中,获得的是测试更加彻底的代码。事实上远不 止这些。测试本身有助于对系统进行描述,清晰的表达你的意图、获得瑕疵率极 低的系统,而且从始至终都是健壮的。同时通过了测试的应用代码让程序员感受 到极大的乐趣和自信。 2 3 2t d d 与其它模型的对比 1 ) 与瀑布模型w a t e r f a l l 的异同 从图2 - 2t d d 的开发流程可知,它是在进行简单概要设计后,先编写测试用 例,然后编码使测试通过,再对代码进行重构来优化代码结构和性能。而传统流 第章x p 与t d d 程则先进行概要设计,之后在概要设计基础上还需详细设计,然后再开始编码实 现详细设计,最后通过测试验证系统。所以说,二者相同之处在于首先都要进行 概要设计,但开始测试进行的阶段和过程却存在很大差异。 2 ) 与v 模型的异同 v 模型是由p a u lr o o k 于1 9 8 0 年提出的,目的在于提高软件开发的效率。它 是最早提出测试并不是一个事后弥补行为,而是一个同开发过程一样重要的过 程。如图2 5 所示,该模型左边是一个向下的开发流程,而右边是一个向上的测 试流程,用v 形象地描述了整个过程。但只适合需求有清晰定义的情况。 需求分析 气i 概囊! 设计 、; 详细设计k 集j 戎移e 腻 。“ 3 - 3 编码 单元测试 。, 魄。g 确魏渺 图2 5v 测试模型 9 刨女测试 妒 系统测试 ? 从图2 - 5 中可发现,t d d 与v 模型共同点都是测试用例设计在编码之前,而 且不同级别的测试与开发阶段并行进行。但二者在执行测试力度上有所不同。v 模型指明测试和开发同步进行,可能的测试用例场景被提出,通过这些测试用例 的必要条件包含在实现中,随后运行这些测试用例以证明实现是无误的。但在 t d d 中,这个过程就更深一步:采用增量式的方法实现测试用例。先编写测试 用例,再运行测试失败,然后编写使之通过的代码。因此在t d d 测试用例的运 行要比其它的测试方法频繁得多,循环粒度也更高。 结合以上对比,用示意图2 - 6 来直观三者在单元测试在不同阶段的表现: p 坠斗、篙订卜裳翥恼一 图2 - 6w a t e r f a l l 、v 、t d d 模型的对比 9 第_ 章x p 与t d d 单元测试是由设计测试用例、创建测试用例、执行测试用例三个阶段组成。 从图2 - 6 可看出在瀑布模型w a t e r f a l l 中,单元测试的所有阶段均发生在编写代码 之后;在v 模型中,设计测试用例在编码之前,但创建和执行测试用例却在编 码之后;而在t d d 中,编码开始之前就开始设计和创建测试用例。 2 4t d d 结合设计模式 目前一些t d d 的质疑者认为它大量的关注于重构,而从来都不去提及模式。 但事实上设计模式和t d d 并不冲突。其实t d d 的重构不只是一种方法,还是一 个过程。持续重构,可提高代码重用性、增强代码灵活性【1 4 】,而设计模式也重在 重用性和灵活性。但是若在一开始就引进大量设计模式,只会增加项目的复杂度。 设计模式经常被滥用其中很大原因就是在一开始就加入了些根本就没必要的 设计模式。极限编程原则之一就是简单,通过重构这个演化过程,使代码能尽量 保持简单,又能提高重用性和灵活性,而且如果发现可以引入某个设计模式,也 可以很好的引入。所以说,t d d 与设计模式并不冲突。 在前一节通过对比t d d 与传统的软件开发方法,发现t d d 摒弃传统软件开 发方法强调前期需精要设计,事先并不花很多时间在设计上( 只作简单概要设 计) 。因而不同的人应用t d d 这种特性可能会导致不同的效果。比如对于丰富编 程经验的人来说,由于他们在编程初期己形成了整个系统的构架,且可以凭经验 来避免设计中产生的冗余、繁琐乃至错误,因此他们采用t d d 可极大的提高开 发效率。但对于经验不足的开发人员,使用t d d 显得比较困难。因为对他们来 说,本身对系统结构还不清楚就动手编码,尽管经过不断的测试,代码的正确性 得到了保证,但整个程序的构架也许变得一团糟。 在这种情况下,先使用设计模式来规范程序的实现方法,可极大的方便日后 的代码重构。对于初步接触t d d 的编程人员来说,结合设计模式进行的测试驱 动开发最合理的方式应该是: 1 ) 花一定的时间做好前期的分析,在研究模式上投入时间; 2 ) 在最初以最简单的形式实现模式,以后再增加其复杂性; 。3 ) 如果使用了一种模式而后发现它无法满足需要时,需转换方式将其修改。 因此,对于有些情况下,在设计模式的指导下,不仅有助于我们完成任务, 而且有助于得到解决问题的最佳办法,从而做出一个优良的设计方案以达到事半 功倍的效果。 l o 第二章x p 与t d d 2 5 客观看待t d d 测试驱动开发当然存在不足之处,与其他方法一样也有它的适用范围。其中 一个潜在的问题就是这要比咖啡因更使人上瘾,就象用t d d 方式具体实践的开发 人员所说的“一旦踏上这条路,就会从此一直希望只采用这样一种方式来编写程 序【2 引。但t d d 并不是对所有的项目都适用。 它的局限主要体现在: 1 ) 测试驱动开发是单元性测试,不是全局性测试。因此在对模型的验证方面起 不到关键作用。 2 ) 由于t d d 缺乏前期的详细设计,对于较大型的项目而言( 如对于设计很重 要必须提前做好精细规划的军事或科研产品,人命关天的医疗设备软件等) , 可能会由于开发人员对项目总体缺乏把握而难以实施t d d 。 3 ) 大约一半的开发人员认为,对于刚刚接触t d d 的人而言,适应t d d 思想有 困难。 t d d 同其它事物一样都有一定的局限性,因而建议应该将t d d 与传统开发 思想相结合,取长补短,做到既能发挥t d d 的优势,又能让开发者更容易接受。 2 6 小结 软件工程是在软件过程、技术和工具三个层次对如何高效率、高质量和低成 本地开发和生产软件而展开的研究。敏捷软件开发方法正是试图将这三者更好的 结合起来,以应对快速变化的需求和对产品高质量的要求。其中极限编程x p 是 最引入注目的、实践最多的敏捷开发方法。作为极限编程x p 的重要实践活动之 一的测试驱动开发t d d 越来越受到人们的关注,并且已经运用于实际的项目开 发中。本章首先研究了x p 的开发特点,并且对比它与传统的开发模型( w a t e r f a l l ) 不同之处,得出x p 更适用于需求快速变动背景下的中小规模的开发团队。然后 然后具体阐述测试驱动开发t d d 这一新型软件开发方式的特点和流程,进一步 分析它对软件开发各个阶段( 需求分析、设计、编码、测试) 的影响以及对比 t d d 与传统软件开发模型和测试方法的异同。由于t d d 本身的局限性,所以对 于初步接触t d d 的编程人员来说,我们提倡t d d 与传统的开发思想、设计模式 等相结合的软件开发方式,以取长补短,做到既能发挥t d d 的优势,又能让开 发者更容易接受。 第三章基于t d d 的t 肌语言实现设计 第三章基于t d d 的t j u l 语言实现设计 在本章中,将按照测试驱动开发方式t d d 的实践步骤“简单设计一测试 编码一重构”,依据硼,( t i a n j i nu n i v e r s i t yl a n g u a g e ) 语言的文法特点,就其 编译过程先给出概要设计,具体实施部分将在下一章详细介绍。 3 1 编译原理 编译程序是指将用高级程序设计语言书写的源程序,翻译成等价的用计算机 汇编语言、机器语言或某种中间语言表示的目标程序的翻译程序【l 丌。编译阶段以 源程序作为输入,以目标程序作为输出,其主要任务是将源程序翻译成目标程序。 编译程序的整个工作过程是划分成一个个阶段进行的,每个阶段将源程序的 一种表示形式转换成另一种表示形式,各个阶段进行的操作在逻辑上是紧密连接 在一起的。一般编译过程可划分成词法分析、语法分析、语义分析、中间代码生 成,优化和目标代码生成等几个阶段。其结构图如图3 1 所示: 图3 1 编译程序的一般结构图 从图3 1 看出,词法分析是编译的第一个阶段。词法分析器,又称扫描器, 1 2 第三章基于t d d 的t j l i ,语言实现设计 它的主要任务是接受输入的源程序,从左至右逐个字符对源程序进行扫描,根据 源语言的构词规则,识别出一个个具有独立意义的单词符号,同时进行词法检查, 把作为字符串的源程序转换成为单词符号串的中间形式。编译程序把单词作为源 程序的最小单位,等待语法分析。 语法分析的基本任务是:根据语言的语法规则,分析源程序的语法结构,即 分析如何由这些单词组成各种语法范畴,如各种表达式、各种语句、程序段或分 程序,乃至整个源程序等等,并在分析过程中,对源程序进行语法检查。 语义分析与中间代码产生这一阶段将对语法分析所识别出的各类语法范畴 进行静态语义检查、分析其含义,并进行初步翻译,产生中间代码。 此外,用表格管理程序建立变量、常量、过程和函数的说明与引用之间的信 息联系。用出错处理程序对编译过程中遇到的错误给出在源程序中出错的位置和 错误性质。 3 2 弧,语言介绍 结合编译课程教学的需要,我们定义了t j u l ( t i a n j i nu n i v e r i s t yl a n g u a g e ) 语 言。t l 语言功能简单,结构清晰、包括的内容相对又较广。它具备了一般高 级语言的必须部分: 1 ) 支持整型、字符型、布尔型三种基本数据类型,还可定义构造类型的数 组,例如定义一维、二维数组。 2 ) 语言具有顺序、分支、循环三种结构,完全结构化。 3 ) 可定义过程、函数,允许递归,但不允许嵌套定义。 因而,t 几,语言的编译程序能充分体现一个高级语言编译程序实现的基本 技术和步骤,比较适合小型编译程序的教学模型。 3 2 1 弧,文法描述 t j l i ,语法的b n f 描述如下: := t d p r o g ; t d e n d := l l l b e g i n ; ) e n d ; := v a r : , ) ; := c o n s t : := , := ,; := t d p r o c ; 第三章基于t d d 的t j u l 语言实现设计 := t d f u n c : ; := ( 【v a r :】 】 ,【v a r :】 ) := l :g = i n tc h a rib o o l := a r r a y 【, i o f := l l := 【+ l 一】 := := 0 i 11 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 := “ 一 := l i := albl iz iaib1 i z :斟l - i 幸l4 ( i ) l 【| 】i := i i ,i ;f :l l := = = i i = i := t r u elf a l s e := i ) := := := := b e g i n ; e n d i i l i := := := i f 1 h e n 【e l s e 】 := w h i l e d o := ( 【 , ) 】) :文简单表达式 := 【+ i 一】 ) :斟i - i o r := 、 _ 、 = 、= = 、o ra n d 等等 5 ) 界符,如, ;:( ) 等等。 由于此次我们采用一趟扫描源程序方式,所以不再把t 肌语言的词法分析 过程单独作为一个阶段,而是把它作为语法分析的一个子过程。当语法分析器在 识别语法结构需下一个单词时,就调用词法分析器。对于词法分析的结果,本论 文将采用二元组形式( 单词种别,单词符号的属性值) 表示识别出来的单词符号。 其中单词种别我们采用整数编码。一种别对应一个编码值,用每个单词在对应符 号表中的相对位置表示该属性值。如下面表格3 - 1 所示: 表3 1 单词种别编码 类别编码值 关键字1 标识符 2 常量3 算符 4 界符 5 数组6 函数 7 过程8 参数 9 回车 1 0 3 3 2 整体架构 根据图3 2 ,设计t j i ,编译程序结构,整个系统的主要功能包括: 1 ) 构造t j l i ,语言的静态符号表、动态符号表。 1 6 第三章基于t d d 的t 肌语言实现设计 2 ) 从词法分析器中获取下一单词。 3 ) 依据所识别出的单词类别转入相应的处理模块,同时更新动态符号表的 内容。 4 ) 当源程序不符合t j u l 的文法规则时,则进入相应的出错处理。 5 ) 将单词转换成属性字,并输出二元组属性字符流。 6 ) 输出动态符号表的内容。 结合上述系统应具备的功能,对其进行概要设计如下: 3 3 3 各功能模块说明 图3 3 整体框架图 1 ) 主程序模块 该模块将接受输入的源程序,调用各个子程序,扫描并处理源程序中的每一 个单词,输出二元组,把信息填入动态符号表,并将结果保存到相应文件中。从 框架图中看出,它需要调用入口转向处理模块,进而依赖于变量处理模块、常量 处理模块、过程与函数处理模块、语句处理等模块来完成整个过程。 2 ) 预处理模块 1 7 第三章基于t d d 的t 几l 语言实现设计 该模块首先过滤掉源程序的注释部分,跳过若干相继的空白符。 3 ) 入口转向模块 通过逐一扫描源程序字符串( 整个源程序实际上可看作字符串流) ,根据首 遇单词的类型决定进入相应的处理模块。例如,若首先遇到是v a r ,则进入变 量处理模块,若遇到是t d f u n c 则进入函数处理模块,若遇到是b e g i n ,则进 入语句处理模块 4 ) 变量处理模块 处理各种类型( 如i n t ,c h a r ,b o o l 类型) 变量的定义,将变量的信息, 比如名字,类型、相对地址、在源程序中引用位置等等存入动态变量符号表中; 如果定义错误或变量名非法,还需调用出错处理模块,给出相应的错误信息;在 分析结果中输出变量属性字。 5 ) 常量处理模块 处理各种类型( 如i n t ,c 雌b o o l 类型) 常量的定义,记录常量的信息, 比如名字,类型、常量值,在源程序中出现过的行号;如果定义错误或变量名非 法,则调用出错处理模块给出相应的错误信息;在分析结果中输出常量属性字。 6 ) 函数、过程处理模块 在函数处理模块,需要处理各种类型( 如i n t ,c h a r , b o o l 类型) 函数的 定义和声明;将函数的相关信息,如名字、类型、入口地址、在源代码中出现过 的行号、函数参数中定义的各种参数,以及参数的指针等填入符号表中;如果函 数定义出错或变量名非法,则需调用出错处理模块给出出错信息;在分析结果中 输出相应的属性字。从主框架图看,该模块还需调用变量处理模块、数组定义模 块及语句处理模块。类似于函数处理模块,过程处理模块将处理过程的定义和声 明,只不过它无返回类型的概念。 7 ) 语句处理模块 处理赋值语句、条件语句、循环语句、过程与函数调用等语句,输出相关的 单词属性字。若语句不符合t j i i ,语言的文法规则,则需给出相应的出错信息。 3 3 4 主要模块架构 1 ) 入口转向模块 该模块主要任务是:根据获取的单词种类转入到相应的处理模块,若源程序 有错,还需提供出错处理。设计其流程框架,如图3 - 4 所示: 第三章基于t d d 的t 几l 语言实现设计 图3 - 4 入口转向模块设计框架 2 ) 变量定义处理模块 该模块将处理各种类型的变量,并将变量信息填入相应的符号表中,若定义 错误,则给出错信息。设计该模块框架如下: 图3 5 变量处理模块设计框架 1 9 第三章基于t d d 的t l 语言实现设计 4 ) 函数处理模块依据整体框架图3 3 ,函数处理模块将处理各种类型函数 的定义和声明,并将函数的相关信息填入符号表中;若函数定义出错, 则需调用出错处理模块给出出错信息。从框架图看,该模块还需依赖于 变量、数组处理模块及语句处理模块。设计其框架如下: 图3 - 6 函数处理模块设计框架 第三章基于t d d 的t j l 兀,语言实现设计 4 ) 常量处理模块 若定义为c o n s t 类型,则入口转向模块就指向常量处理模块。该模块将处 理各种类型的常量,将常量信息填入常量符号表中,若定义错误,则给出出错信 息。设计该模块框架如下: 图3 7 常量模块设计框架 这只是具体实施前做的概要设计,在第四章具体实践部分随着测试进度的 推进,设计趋于完善。以上是对一些主要处理模块所做的简单设计框架,对于整 体框架图中其它模块的处理流程就不再一一列举出来。 , 第三章基于t d d 的t 肌语言实现设计 3 4 符号表 3 4 1 符号表作用 在编译程序中,符号表是用来存放源语言程序中出现的有关标识符的属性信 息【1 7 1 。这些信息集中反映标识符的语义特征属性。在词法分析及语法分析过程中 将不断积累和更新表中的信息,并在编译程序的各个阶段,按各自的需要从表中 获取不同的属性信息。不论编译策略是否分趟,符号表的作用和地位是完全一致 的。 收集符号属性 上下文语义的合法性检查的依据 作为目标代码生成阶段地址分配的依据 语言符号可分为关键字( 保留字) 符号,操作符符号及标识符符号等等。它 们之间的主要属性有较大差别。因此通常为它们建立不同的符号表,但也有些编 译程序也将关键字符号与标识符符号建立在同一符号表中。 3 4 2 设计符号表 根据t 肌程序语言的文法特点,由于单词种别不同,若将全部单词存放在 同一张符号表中,无论是查找还是修改,管理起来都十分费力。所以这里将采用 不同种别对应不同符号表的方

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论