(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf_第1页
(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf_第2页
(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf_第3页
(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf_第4页
(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf_第5页
已阅读5页,还剩59页未读 继续免费阅读

(计算机软件与理论专业论文)基于mock+object测试的契约不一致错误的研究.pdf.pdf 免费下载

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

文档简介

中山人学硕一l :学位论文基于m o c ko 场e c t 测试的契约4 i 一致错误的研究 论文题目:基于m o c ko 场e c t 测试的契约不一致错误的研究 专业:计算机软件与理论 硕士生:冼汉君 指导教师:李文军教授 摘要 在理想模型中,面向对象程序的单元测试应该既能全面覆盖被测试类的所有 行为和状态,又能使其独立于其它类的实现。然而,由于绝大部分类都会与其它 类存在依赖关系,因此单元测试的全面性和独立性无法同时满足,这就使得软件 质量难以得到保证。 在单元测试中引入桩在理论上可以解决这个问题,然而当所需的被依赖类的 数量较大且实现复杂时,即使是当今被广泛接受的特定桩,也会因为创建难度过 高而无法在单元测试中广泛应用。这时,由于m o c ko b i e c t 更强调类间接口的交 互,完全忽略被模拟类的实现,可以作为桩的合适替代品。桩和m o c ko b j e c t 的 混合使用是在实际应用中使单元测试同时具有全面性和独立性的一个有效途径。 然而,m o c ko b i e c t 对被模拟类的极大简化使得类与类之间契约可能存在的 不一致性被隐藏,涉及类间交互的单元测试用例不能测出契约不一致错误。所以 本文的第一个贡献是通过理论分析和实验数据来讨论m o c ko b i 瞅对契约不一致 错误的隐藏问题。 本文第二个贡献是提出了将单元测试用例重用到集成测试的方法,使程序在 集成测试时付出较少的额外代价来修改测试用例,即可测出在单元测试时被隐藏 的契约不一致错误。这种方法既保持了因为在单元测试中使用m o c ko b j e c t 所带 来的优点,又可以在不产生新的测试用例的情况下发现契约不一致错误。为了验 证本方法的可行性,本文将通过一个实验来说明通过这种重用机制,隐藏的契约 不一致错误可以被发现。 关键词:单元测试,m o c ko b j e c t ,集成测试,契约不一致性 i i l i ,山大学硕十学位论文丛丁m o c ko b j e d 测试的契约卜致错误的研究 t t t l e :r e v e a l m gc o n t r a c ti n c o l l s i s t e n c yf a i l u r e s 访m o c ko b j e c t - b a s e dt e s t i i 唱 m 勾o r :c o m p u t e rs o r w a r ea n dt h e o 拶 n a m e :x i a l lh 锄j u n s u p e i s o r :p r o 角s s o r “w r e n j u n a b s t r a c t i d e a l l mm l i tt e 砒i n gs h o u l do no n eh a n d 龟l l yc o v e rt h ei i i l p l e m e n t a t i o nw i t h i l la c l a s s ,锄i do nt h eo t h e rh a i l db ei n d e p e n d e n t 自o mo t h e rc l 硒s 懿w i t hr c s p e c tt 0 o b j e c t o 订e n t e dp r o 缪锄s h o w e v d u et ot h ed 印e n d e n c yc o m m o i l l y 南u n db e t w e t w oc l a s s e s ,t h e s e 锕od e n l a n d sc a nn o tb en l e ta tm es a n l et 曲e sn l _ bp r e s e n t sas o l u t i o nt ot 1 1 i sp r o b l 锄n e v e r t h e l e s s 咖bb c c o m e si n f e a s i b l e w h e i lt h el m m b e ro fc l a s ss t u b b e di s l a r g e 甜l de a c ho ft i l e m1 1 0 l d sc o n 】p l e x i m p l e i n e n t a t i o n i nt h i sc a s e ,m o c ko b j e c tc a l lb eas u b s t i t u t eb e c a u s ei t 钮驴h a s i z 豁 i l l t e r 伍c ei m e r a c t i o na n d 逗i l o r e ss e m a n t i ci i l 如m a t i o no ft h ec l a s sm o c k e d am i x t u r e o fs t l l bw a ya n dm o c ko b j e c tw a ys u g g e s t s 孤e 彘c t i v cs o l u t i o nt ot h ed 印即d e 鹏y p r o b l e i i li l lu i l i tt e s t i r 塔 m o c ko b j e c tm a l ( e sag r e a t e s ts i m p l i f i c a t i o nt ot h ec l a s sm o c k e d ,w h i c ht 朋d st o c o n c e a lc o n t r a c ti r l c o n s i s t e i l c y b 怡nt h o s eu n i tt e s tc 弱e sc o n c e n l i i l gc o m r a c t sc 锄1 1 0 l o n g e rr e v e a la r l yc o n t r a c ti n c o n s i s t e l l c y 伍i l u r e t h e r e f o r c ,t h i st h e s i sf i 】s t l yd i s c u s s 鼹 t h i sc o n c e a l i n gp r o b l e mb yt h e o r e t i c a la m l y s i sa n de x p e r i n l e n t a lr e s u h t l l i st h e s i ss e c o n d l yp r o p o s e saw a yt or e v e a lt h ec o n t r a c tm c o n s i s t e i l c yf a i l u r e s t h ea p p r o a c ht a l 【e sa 批1 t a g eo fm o c kc i b j e c tw l l i l ea v o i d i i l gt l 圮p r o b “锄i tb r i n g s t 0p r o v ct h ee 脏c t i v e n e s so ft l l i sa p p r o a c h ,a i le x p e r i m e n ti sc o n d u c t e dt 0s h o w t h i sa p p r o a c hr e v e a l st h ec o n t m c ti f l c o i l s i s t e n c yf a i l u r e s k e y w o r d s :u n i tt e s t i n g ,m o c ko b j e c t ,i n t e 寄砒i o nt e s t i n g ,c o n t r a c ti 1 1 c o n s i s t e n c y i l i 山大学硕十学位论文聃丁m 0 c ko 巧e c t 测试的契约声致错误的研究 论文原创性声明 本人郑重声明:所呈交的学位论文,是本人在导师的指导下,独立进行研究 工作所取得的成果。除文中已经注明引用的内容外,本论文不包含任何其他个人 或集体已经发表或撰写过的作品成果。对本文的研究作出重要贡献的个人和集 体,均己在文中以明确方式标明。本人完全意识到本声明的法律结果由本人承担。 学位论文作者签名:7 蔹瓣 日期:7 岫绰箩月留日 - - 山大学硕十学位论文珐丁m o c ko 巧c c t 测试的契约小致错误的研究 学位论文使用授权声明 本人完全了解中山大学有关保留、使用学位论文的规定,即:学校有权保留 学位论文并向国家主管部门或其指定机构送交论文的电子版和纸质版,有权将学 位论文用于非赢利目的的少量复制并允许论文进入学校图书馆、院系资料室被查 阅,有权将学位论文的内容编入有关数据库进行检索,可以采用复印、缩印或其 他方法保存学位论文。 学位论文作者签名:1 烧7 予黟 日期:埘年歹月9 日言篓纛秭日期:衙箩月星印 n i i 山大学硕十学位论文坫丁m o c ko b j e c t 测试的契约小。致错误的研究 引言 软件测试是保证软件质量的最重要的手段【l 】,而单元测试由于其易操作性, 在软件开发生命周期可以在较早的阶段实施,因而是最基本和最普遍的测试类 型。同时,单元测试被证实是最有效的测试方法,即在较早阶段能够发现最多错 误。 在面向对象程序中,单元测试中的单元通常指的是单个类。单元测试负责对 被测试类的所有属性,方法,以及方法的有效序列进行测试。具体来说,单元测 试需要检测所有属性的类型、初始值、作用域、取值范围,方法的前置条件和后 置条件,方法的有效序列的j 下确性等等。 理想的单元测试应该既能全面覆盖被测试类的所有行为和状态,又能使其独 立于其它类的实现。覆盖的全面性是单元测试乃至整个软件测试中都需要致力达 到的指标【2 】,因为只要有未覆盖到的代码或者分支,就意味着存在软件缺陷的可 能。独立性【3 】贝0 是单元测试中的特殊要求。因为单元测试着眼于单个类内部的行 为和状态缺陷,所以如果能够将被测试类与其它外围类隔离,所测出的错误就可 以完全反映被测试类的真实状况。反之如果被测试类与外围类有太多联系,所测 出的错误就很可能受到外围类的影响。 然而,由于绝大部分类都会与其它类有依赖关系,因此单元测试的全面性和 独立性无法同时满足,这就使得软件质量难以得到保证。几乎所有类都会与至少 一个其它类存在依赖或被依赖关系,这种关系可能是继承关系( 泛化) 、关联关 系、聚合关系和组合关系【4 1 。因此除了少数仅存在被依赖关系的类+ 可以得到全 面和独立的测试外,其它类在测试依赖其它外围类的部分时无可避免地需要在全 面性和独立性之间作出抉择要么与被依赖的外围类一起测试来满足全面性, 要么不测试该部分来满足独立性。 桩为上述问题提供一种可能的解决方法。通过使用桩来模拟被依赖类的部分 或全部特性,被测试类可以在桩的帮助下完成单元测试。然而桩的构建实际上是 对于同一功能或者模块的二次实现,这就导致如下三个问趔5 】:一是无法保证桩 即u m l 类图巾出度为零的类 l i i - 山大学硕+ 学位论文躺丁m 0 c ko 场e c t 测试的契约小致错误的研究 的正确性,即无法肯定桩的实现是绝对正确而并非对原有功能或模块的简单重 复;二是无法保证桩能对真实实现简化;三是桩本身可能存在错误。虽然当今被 广泛接受的特定桩能够对被模拟类的行为作很大程度上的简化,但当所需的被依 赖类的数量较大且实现复杂时,特定桩依然因为创建难度和成本太高而无法在单 元测试中广泛应用。 m o c ko b i e c t 为上述问题提供另一种可能的解决方法。与桩相比,m o c k o b i e c t 更强调类间接口的交互,完全忽略被模拟类的实现,是对特定桩的进一步 简化,是使单元测试同时具有全面性和独立性的一个有效途径。从软件缺陷的发 现时间来说,如果一个缺陷在单元测试未被发现而在集成测试中被发现,必定属 于下列三种情况之一:1 、单元测试不够充分,导致本应在单元测试测出的缺陷 未被发现,通过补充适当的单元测试用例可以测出此类缺陷;2 、该缺陷是由于 类间接口契约的不一致性造成的;3 、该缺陷无法在单元测试阶段测出,因为它 属于业务逻辑上的错误,必须通过构建横跨多个类的事件序列来测出,此时必须 为此构造基于规范或者说是基于用户需求的测试用例才可以测出。在上述三种情 况中第一种和第三种情况分别属于单元测试和集成测试的范畴,而第二种情况的 缺陷则既可能在单元测试中发现,也可能在集成测试中发现。然而,m o c ko b i e d 对被模拟类的极大简化使得类与类之间的契约不一致性没有显现出来,涉及类间 交互的单元测试用例不能测出与契约不一致错误,这意味着第二种情况的错误将 因此更不能在单元测试阶段被发现,而加重了集成测试的负担。 所以能否在保持m o c ko b i e c t 低成本的优势下,在不增加集成测试成本的情 况下发现因契约不一致错误将非常具有现实意义。 第一章将对本文涉及领域的相关背景进行介绍,第二章叙述本文的研究动 机,第三章从理论分析的角度说明m o c k0 b j e c t 会隐藏契约不一致错误,第四章 通过实验再次检验第三章的结论,并提出解决方法,第五章对解决方法进行实验 评估并分析其合理性,第六章进一步讨论相关工作以及其它内容,第七章总结本 文内容并对本研究的未来前景进行展望。 2 i i 山大学硕+ 学位论文 基_ 丁m o c ko b j c c t 测试的契约小。致错误的研究 第一章背景知识 1 1 单元测试和集成测试 1 1 1 术语定义 软件测试嘲:通过分析软件组件来检测现有状态和所需条件差异,并对软件 组件的特性进行评估。 单元测试【7 1 :对单个硬件或软件单元,或者由若干相关单元构成的单元组的 测试。 集成测试【7 】:对软件模块,硬件模块,或者软件和硬件模块之间组合后的测 试,来评价它们之间的交互作用。 1 1 2 单元测试 面向对象程序设计语言的出现影响了程序员进行软件测试的方式,传统的自 底向上的测试方式,在面向对象程序中依然适用,只不过这时最底层的构成部分 是类。单元测试【引,顾名思义是隔离地执行一个代码单元,并将实际运行所得和 期待结果相比较【1 1 。单元测试被证实是最有效的测试方法,即在较早阶段能够发 现最多错误。因此单元测试被越来越多的丌发人员所接受。数据显示,超过7 9 的微软开发人员都会进行单元测试【9 】。 在极限编程【1 0 】所推崇的测试驱动的开发方法,单元测试更被作为最根本的 要素来贯穿整个开发过程。代码实现是为了符合测试所需而进行增量式添加,而 一旦实现发生了改动,单元测试又将重新进行,这通常被称为回归测试。由于回 归测试和极限编程已经超出本文讨论范围,故不再深入介绍。 1 1 3 集成测试 山大学硕十学位沦文耩丁m o c ko b j e c t 测试的契约小致错误的研究 点,对编码风格的要求也是在各实现工具中最低的,因此被选定为本文实验的 m o c ko b j e c t 实现工具。 1 3 契约式设计 1 3 1 概述 契约式设计【2 4 】在由b 咖锄dm e y 盯在1 9 9 2 年首次提出,并详细定义了各种 相关术语和规则。当前,契约式设计在工程上应用的优势已经被广泛接受,不少 文献【2 5 】【2 6 1 已经通过实验的角度论证了契约式设计的优劣。 契约式设计的思想来源于h o a r e 【2 7 1 的正确性理论【2 8 】,在软件领域的应用基于 如下情况:从更抽象的层次上分析,程序中的任何一个任务都是由子任务构成的, 这些子任务既可以是程序语句序列,也可以是若干次函数调用。当子任务的实现 是通过函数调用来完成时,客户端+ 和供应方+ 之间就存在契约。这种契约法则定 义了供应方行为的最小集合和客户端期望行为的最大集合。 这种契约在程序中通过断言来描述,而最常见的断言则包括前置条件,后置 条件和不变式。前置条件定义了供应方被调用前需要满足的条件,后置条件定义 了当调用结束后返回到客户端时应满足的属性,不变式表示在一定有效域内的元 素+ 都必须满足的约束。 1 3 2 契约不一致错误 一般来说,供应方的前置条件越强,客户端的任务就越重,因为这等于把供 应方对输入状态的部分处理交由客户端完成。反之,供应方的前置条件越弱,客 户端的任务就越轻。无论是上述两种情况的哪一种,在契约一致性上都不存在问 题。 1 即被凋_ j 函数 2 即调用方 3 这里指的“元素”既可以是函数,变量,在面向对象语言中也可以是类。 1 2 f - 山大学硕+ 学位论文肚丁m o c ko b j c c l 测试的契约小致错误的研究 但是,当供应方与客户端所期待的契约不一致时,就会出现错误。这种错误 对应地分为前置条件的不一致,后置条件的不一致和不变式的不一致。这类不一 致性导致的错误可能导致供应方和客户端对某部分操作的重复实现,也可能导致 分支的缺失等等,具体例子请参见2 2 节。 山大学颀十学位论文璀rm o c k0 b j e c t 测试的契约小。致错误的研究 正如1 2 5 节所述,m o c ko b i e c t 在单元测试的部分场合比桩有优势,两者的 混合使用是解决测试依赖性的有效途径。然而,m o c ko b j e c t 的引入导致了契约 不一致错误的隐藏问题,且问题的严重程度超过使用桩的情况。 所以,本文的研究动机首先是讨论m o c ko b j c c t 相比桩是否更容易隐藏契约 不一致错误,然后研究如何能够在引入m o c ko b j e c t 后通过采取一种低成本的方 法来发现这类缺陷,以免使发现成本转嫁到集成测试阶段。 2 2m o c ko b j e c t 隐藏契约不一致错误的例子 2 2 1 前置条件不一致的错误 例如,一个简单的计算算术平方根的程序包括c o i l s 0 1 e 类用于接受用户输入, s q r t 类用于计算算术平方根。具体流程是:c 梳l c 初始化程序之后,接受用户 输入的一个数,然后调用s q n 类的n o a tg e t s q n ( n o a tx ) 来求解算术平方根并把结 果返回,然后输出到控制台。c o i l s o l e 类和s q r t 类分别做单元测试,其中c o n s o l e 类由于依赖s q r t 类,所以测试用例带有s q r t 类的仿真体。假设c o m o l e 类期待 s q r t g e t s q n ( ) 对输入数据进行是否大于o 的判定,而s q r t 类的g e t s q n o 则期待被 调用前已经保证了参数必定大于o ,也就是说,在这种情况下,双方的接口契约 出现了不一致性,且被依赖类的接口契约前置条件强于被测试类的期望。显然这 是一个契约不一致错误。此时,当用户输入数值为负数时则程序会出错。 如果使用特定桩来模拟s q r t 类,该特定桩在构造时应该同时满足前置条件 强于s q r t 类且弱于c o n s o l e 类,但在这个例子中是不可能同时满足的。当满足前 者时c o n s 0 l e 类在单元测试可以发现这个契约不一致错误;当满足后者时则无法 发现,除非将特定桩与s q n 类真实实现作比较。所以这种情况下特定桩有一定 可能发现契约相关的缺陷。 如果使用m o c k0 i b j e c t 来模拟s q r t 类,其期望规则恒为c o n s o l e 类期望的真 子集,所以无法发现契约不一致错误。两个类在各自的单元测试中都无法发现这 个错误。因为就s q r t g e t s q r t ( ) 而言,测试用例的测试输入都会设计成大于等于o , 因为这是它的前置条件,即使对于小于0 的输入,出现异常也被认为是正常的行 1 5 r fr 山大学硕士学位论文螭rm o c ko b j e c t 测试的契约4 i 致错误的研究 为而非错误;而就c o i l s o l e 类而言,由于采用了s q n 类的m o c ko b j e c t ,所以无 论任何数值,c o i l s o l e 类都期待s q r t g e t s q n ( ) 能够处理,即m o c ko b j e c t 契约的前 置条件弱于被依赖类,因此也不存在错误。由于m o c ko b i e c t 只是简单地按照 c o n s 0 1 e 类的需求来期待s q r t 类的返回值,而完全忽略其实现的语义,因此无法 发现这种接口契约不一致错误。于是,这样一个由于契约不一致而出现的错误就 在单元测试中被隐藏了。 2 2 2 后置条件不一致的错误 某议程管理系统中的m e e t i i 培类有两个成员变量s t a r t t i m e 和e n d t i m e ,所有 新创建的m e e t 崦对象都必须保证s t a r t t i m e 定义的时间在锄d t i m e 之前。为了 比较两个时间的先后顺序,需要调用t i m e 类的b 0 0 1 n b e 如似t i l l l et ) 来判定。由 于m e e t i n g 类依赖t i l t l e 类,所以要为t i n l e 类做仿真体。在时间先后判定时,假 设m e e t i l l g 类期望当两个时间相等时t i m e b e 如r e ( t i 嘲i ct ) 应返回缸1 l e ,而t i m e 类 的真实实现中这种情况下则返回f a k 。可见,双方契约的前置条件是相同的, 都是t i m e 对象,但在边界条件上出现不一致性,显然这也是一种契约不一致错 误。 如果使用特定桩来模拟t i l l l e 类,显然特定桩契约的前置条件与t i m e 类和 m e e t i l l g 类的期望相同,具体构造时返回值可能会因为对t i m e 类的简化而与t i m e 类一致,也可能按照m e e t 访g 类的需求而与其一致。前者的情况下m e e t i n g 类调 用t i m e 类和调用特定桩所获得的返回值是完全一致的,所以在特定桩替代t i m e 类真实实现后依然可以测出契约不一致错误,而后者的情况下则无法测出契约不 一致错误,但可能可以揭示特定桩与t 硫e 类的不一致性。 如果使用m o c ko b j e c t 来模拟t i i i l e 类,由于m o c ko b j e c t 的期望规则完全按 照m e e t i i l g 类的期望来设计,所以m o c ko b j e c t 在面对两个时间相等的情况时必 定返回t r u e ,无法测出任何契约不一致错误。而t i m e 类本身的单元测试也认为 这种情况下返回龟l s e 是正确的行为,所以也没有发现错误。契约不一致导致的 错误因为m o c ko b i e c t 的引入而被隐藏了。 1 6 山大学硕十学位论文笨- 丁m 0 c ko 场e c t 测试的契约小致错误的研究 试类所期望的契约的前置条件。由于m o c ko b j e c t 的期望规则是忽略语义而直接 进行交互,这种特性使得期望规则恒等于被测试类对仿真体的期望,所有契约相 关的缺陷均无法在引入m o c ko b j e c t 后被发现。 综上两点不难看出,从被测试类的角度出发,桩等价于被依赖类,所以通过 组装真实的被依赖类而发现的契约不一致错误依然可以在使用桩的情况下发现, 即使用桩来替代被依赖类并没有隐含契约不一致错误。从更坏的角度考虑,即使 桩的实现出现部分偏差,也存在一定可能可以发现这类错误。然而m o c ko b j e c t 只提供被测试类期望契约的子集,且期望规则恒为被测试类对仿真体的期望的子 集,所以必然存在契约不一致错误会因为引入m o c ko b j e c t 而无法在单元测试阶 段发现。 3 2 符号化分析 上一节从一般意义上分析了m o c ko b j e c t 相比桩更容易隐藏契约不一致错 误,本节将使用符号化分析来得出同样结论,并分析出桩可以发现契约不一致错 误而m o c ko b j e c t 不可的所有情况。 3 2 1 基本符号定义 c j 被依赖类 c ,被测试类 观被测试类期望的仿真体或被依赖类 巩通用桩 双) 嚣特定桩 叻。啪c ko b j e c t 厂c 函数厂是类c 的成员函数 1 9 i | i 山大学硕十学位论文接丁m o c ko b j e c t 测试的契约4 i 致错误的研究 【门函数厂的基调 z 厶函数z 内部实现存在对以的调用 d ,函数厂的前置条件( 定义域) f e 中被c 。所依赖的函数的集合,即 f = 厂i 厂g 且可e 使缈 - 厂) ,。e 期待仍或q 包含的函数集合,即 ,。= 厂。i 厂8 观且矽f 使得【厂。】= 【厂f 】) ,斟觋中被e 所依赖的函数的集合,即 f 黟= 笋l 厂笋仍黟且可e 使缈 - 厂芦) f ”疆k 中被e 所依赖的函数的集合,即 ,”= 厂”i 厂嚣7 z k 且j 厂e 使缈 _ ”) ,聊玻。中被e 所依赖的函数的集合,即 ,”= ”i 厂”巩且可e 使缈 - 厂” z z e ,类似定义以,厶,丘,厶 【f 】函数集合f 中所有函数的基调 3 2 2 定理和运算符定义 定理1 : ,】= ,。】= 【,芦】= 【,“】= 【f ”】 证明:显然成立,虽然被依赖类中可以存在其它函数,但被被测试类所依赖 的函数集合必然等于被测试类期望依赖的函数集合,且由于这种依赖是调用关 系,所以基调也完全一致,故【e 】= c 】,同理可证其它等式成立。 定义1 :函数延拓 i 山大学硕十学位论文脯丁m 0 c ko 巧e c t 测试的契约小致错误的研究 函数歹被称为函数厂的函数延拓当且仅当满足:坛d ( x ) = 7 ( 工) 。记为 ,扣f 定义2 :类延拓 一个类或仿真体c :被称为c i 的类延拓当且仅当满足: 眠1 ,1 玑2 ,2 2 q 六1 。记为c :仃。q 定义3 :差域 一个类或仿真体g 在函数五上对q 的差域被定义为: c 2 厶c l :缸l 工研彳,z 且砰( x ) 爿( 曲) u 驯x 谚噬 一个类或仿真体c :对c i 的差域被定义为: g ! q :i :二:l ( c 2 厶c 1 ) 定理2 :c 2 c r cc ljc l 旦g = 矽 证明:当c 2 吒c l 时,按定义2 和定义1 1 f 1 现2 f 2 溉d ( 功= 彳( 力 按定义3 g 厶g :缸jx 磁爿f t 且爿( x ) 砰( 功) u xx 硝磷) :矽 故c l 三c 2 = 矽 3 2 3 分析和证明 前提假设: ( 1 ) e 仃。囝。; 2 l i 山大学硕十学位论文脯丁 m 亳| ko 巧e 妻;测试的契约小致错误的研究 函数歹被称为函数厂的函数延拓当且仅当满足:坛d ( x ) = 7 ( 工) 。记为 ,扣f 定义2 :类延拓 一个类或仿真体c :被称为冀i 的类延拓当且仅当满足: 眠1 ,1 玑2 ,2 2 q 六1 。记为c :仃。q 定义3 :差域 一个类或仿真体g 在函数五上对q 的差域被定义为: 妻;厶蓁l :缸l 工研彳,z 且砰( x ) 爿( 曲) u 驯x 谚噬 一个类或仿真体c :对蓁l 的差域被定义为: g ! q :| | 蓁| | ( 雾i 厶冀i ) 定理2 :雾i 爹;蓁! j 蓁| 旦g = 矽 证明:当冀;吒f | 时,按定义2 和定义1 1 f 1 现2 f 2 溉d ( 功= 彳( 力 按定义3 g 厶g :缸jx 磁爿f t 且爿( x ) 砰( 功) u xx 硝磷) :矽 故薹! 三妻;= 矽 3 2 ;薹分析和证明 前提假设: ( 1 ) e 仃。囝。; 2 l | l 山大学硕+ 学位沦文 螭丁- m o c k0 b j c c t 测试的契约一i 致错误的研究 ( 2 ) 被依赖类前嚣条件强于被测试类的期望,当被测试类的合法测试输入在 被依赖类中没有定义而在特定桩中有定义且后置条件不一致时,此时桩虽然可能 前置条件弱于被测试类,但由于在被依赖类中没有定义而容易出错,从而出现后 置条件与被测试类存在不一致。这是在无法构造桩的情况下勉强构造而出现的情 况; ( 3 ) 特定桩前置条件强于被测试类的期望,当被测试类的合法测试输入在特 定桩中没有定义而在被依赖类中有定义且后置条件不一致时,当测试输入覆盖到 两者的交集时被测出。这是罕见的桩构造完全失败的情况; ( 4 ) 特定桩和被依赖类的前置条件均强于被测试类,当被测试类的合法测试 输入均在特定桩和被依赖类中没有定义时,这是根据被依赖类来构造桩实现,没 有出现误差的情况。 ( e 三签) n ( e 三q ) 矽的证明同理可得 对于上述四种情况,( 1 ) ( 4 ) 是在桩构造完全没有出错的情况下分别测出契约 不一致错误中前置条件和后置条件不一致的错误。只要测试输入覆盖到上述四种 情况时,契约不一致错误可被发现,而m o c ko b j e c t 则始终不能发现,从而从理 论分析的角度上得出m o c ko b j e c t 比桩更易于隐藏契约不一致错误的结论。 巾山大学硕士学位论文 脯丁m o c ko 巧e d 测试的契约1 i 致错误的研究 第四章实验设计及解决方法 上一章通过理论分析得出了m o c ko b j e c t 会隐藏契约不一致错误的结论,本 章首先将通过实验的手段再次检验这个结论,在此基础上针对m o c ko b j e c t 的这 一弊病本章将提出一种解决方法,这也是本文的另一重要贡献。 4 1 实验设计思路和总框架 为了说明m o c k0 切e c t 对契约不一致错误的隐藏,首先必须找出一个存在此 类错误的程序,通过引入m o c k0 b j e c t 进行单元测试,对所发现的错误进行回溯, 证实没有发现契约不一致错误,然后通过使用本文提出的解决方法,使真正存在 的契约不一致错误被发现,从而说明m o c k0 q e c t 的确存在隐藏契约不一致错误 的弊病。具体操作应包含如下步骤: 1 、实验环境和被测程序的选择 实验环境包括测试环境,m o c k0 i b i e c t 的实现工具,程序设计语言的选择等 等。理论分析时的理想环境并不一定能在现实中找到同样实现。 被测程序的选择同样非常重要,被测程序必须具有代表性,同时必须拥有契 约不一致错误,而这在测试之前是无法获知的。 2 、证实m o c ko b j e c t 的引入使单元测试未发现契约不一致错误 这个阶段丰要负责完成单元测试,收集测试数据并分析,得出m o c ko b j e 髓 的引入未能找到契约不一致错误的结论。具体包括如下步骤: ( 1 ) 单元测试用例的设计和单元测试的运行 单元测试用例的设计是否有足够的覆盖度,很大程度上决定了契约不一致错 误能否有机会被发现。如果测试输入覆盖度过低,那么引入m o c ko b j e c t 后未能 发现缺陷将会被质疑是因为测试覆盖度问题导致。 单元测试用例的设计还包括m o c ko b j e c t 的设计,这也关系到m o c ko b j e c t 能否像上一章理论分析的前提条件一样被e 类延拓。 蚺丁m o c ko b j e c t 测试的契约小。致错误的研究 3 、提出方法并证实被测程序确实存在契约不一致错误 这个阶段提出一个可发现契约不一致错误的方法并加以实施,最终证实被测 程序确实存在契约不一致错误,从而最终说明被测程序在包含契约不一致错误的 情况下,m o c ko b e c t 的引入使得这类缺陷被隐藏的结论。 ( 1 ) 单元测试用例的选择 为了试图发现契约不一致错误,必须对所有单元测试用例作筛选,选出有意 义的可用的测试用例作进一步处理。 ( 2 ) 单元测试用例的重用策略 这是本章用于解决m o c ko b i e c t 这个弊病而提出的方法,如何重用单元测试 用例,通过重用为何可以解决m o c ko b j e c t 的弊病都是讨论的重点。 ( 3 ) 组装顺序策略的结合 解决重用策略之后单元测试用例将在集成测试阶段重新测试,所以就面临集 成测试中的组装顺序策略问题。 对应框架图如图4 一l 所示。 实验环境和被测l契约不一致错误的l 程序的选择l不可测性l ( 选秽户 固, 弋 单元k 试 霜 7 影 图4 一l 实验和解决方法总框架 - 山大学硕十学位论文 斌丁m 0 c k0 巧e c t 测试的契约4 i + 致错误的研究 学生学号 实验项目 表4 1 被测程序统计数据 0 7 2 1 3 + 议程管理系统 4 3 契约不一致错误的不可测性 4 3 1 全面和独立的单元测试用例 在引言部分已经提到,当前单元测试的全面性和独立性难以同时达到,而桩 和m o c k0 断c c t 都是解决的途径。所以本实验在单元测试环节与传统单元测试的 最重要差异在于单元测试用例的设计原则可以单单从被测试类本身出发设 计全面而独立的测试用例,无须考虑依赖无法解决的问题和相关类群组合的问 题。也就是说,测试用例的设计者可以假设所有其它类都准备好并且都是完全正 确的,而仅仅针对当前这个“嵌入”的类进行测试。之所以要为本实验定下这样 的设计原则,是为了让所有的依赖关系都暴露出来,并且所有的依赖关系都通过 m o c ko b j e c t 的解决,这就使得m o c ko b ! j e c t 全面涵盖了所有契约不一致错误, 是否能发现这类缺陷将完全是m o c k0 啊e c t 的责任。 下面陈述这种设计原则上的根本差异对单元测试提出的要求及这种要求的 原因: 1 、测试用例必须覆盖所有类中的所有函数。 传统单元测试很少会对被所有类的所有成员函数都都进行测试,除非它们对 其它类没有或者有极少的依赖,而会把部分对外依赖性强的函数留待集成测试阶 段时测试。而本实验则要求在单元测试阶段就把所有函数都纳入测试范围,不管 其依赖性强弱。例如某程序中类d a t a m a n a g e r 在成员函数i n i t ( ) 中创建了t i m e 对 象和m e e t m g 对象,也对m e e t 吨对象作了赋值,如下面例子所示。这些对象对 应的类显然在d a t a m a n a g e r 类之外。 i i i 山大学硕+ 学位论文辕丁m o c ko 巧e c t 测试的契约小致错误的研究 表4 2d a t a m a n a g e r i n i t ( ) 的部分代码实现 p u b k cc l a s sd a t a m a n a g e r p u b cs t a t i cv o 试i 1 1 i t ( ) t h m w sm y e x c 印t i o 粥 d a t a m a 瑚g e r i i l i t m e e t i i l g = n e wm e e t i n g ( l o v e s t o 搿”,”w i l l ”,”c a t h e r i n e ”, n e wt i m e ( ”2 0 0 6 一l 一1 - l3 ”) ,n e wt i m e ( ”2 0 0 6 - l - l 一0 ”) ) ; 按传统做法,如果要对类d a t a m a i l a g e r 进行单元测试,首先要判断这个类对 其它类的依赖关系,所需桩的数量,创建桩的成本大小,从而决定哪些成员函数 适合单元测试,哪些应该留待集成测试组装到一定程度后测试。就i l l “( ) 函数而 言,由于它要求创建两个特定桩分别用于解决对t i l i l e 类和m e e t i l l g 类的依赖问 题,故更可能被归类到暂时忽略而不进行测试的集合,留待集成测试时组装了 t i i i l e 类和m e e t i n g 类之后再进行类群测试。然而,本实验则要求为t h e 类和 m e e t i i l g 类创建仿真体来支持i l l i t ( ) 函数的单元测试。 原因:在传统单元测试中,被忽略的函数往往是类的边界,即与其它类有交 互的部分,而这部分正是契约不一致错误最可能发生的地方。例如上述例子中 i n i t ( ) 中调用了t m 类和m e e t i n g 类的构造函数,这两处就是契约不一致错误发 生的可能之处。因此要求在单元测试时将所有类所有函数纳入测试范围,是为了 保证所有可能的契约不一致错误都不会因为对应的函数没有被测试而未被发现, 保证测试结论的可靠性和全面性。 2 、所有的单元测试均在被测试类单独存在的情况下进行 如上文所述,所有类所有函数都在单元测试中覆盖到,而依赖关系也全部通 过m o c ko b i e c t 来解决,所以被测试类完全可以单独存在,在没有任何其它类支 持的情况下完成单元测试。这一点要求也与传统单元测试有差别,传统单元测试 对于对外依赖性强的函数或类会采取集成测试时类群测试的方法进行,这时被测 试类并非单独存在而是已经与其它类组装。 原因:因为本实验旨在验证m o c ko b j e c t 对契约不一致错误的发现的影响, 因此如果被测试类与被依赖类组装后对接口进行测试,就使得m o c kc i b j e c t 没有 存在的价值,而如果部分使用m o c k0 b e c t 而部分允许组装进行测试,又会使得 实验结果不够全面。本实验在遵循本要求的情况下允许被依赖类以纯接口方式存 山大学硕十学位沦文轼丁m 0 c ko b j e c t 测试的契约4 i 。致错误的研究 4 3 2 1 确定m o c ko b j e c t 对应的被依赖类 要确定所有m o c ko b e c t 对应的被依赖类,必须找出被测试类的所有依赖关 系。这里并不意味着m o c ko b i e c t 会好像特定桩一样针对每个被依赖类创建一个 特定桩。因为m o c ko b j e c t 期望规则往往横跨多个被依赖类,所以形式上与特定 桩有很大区别,但两者都需要为被测试类找出所有依赖关系。 找出所有依赖关系的第一个途径是通过u m l 类图确定。然而,在实际使用 u m l 类图时往往会忽略部分弱依赖关系不加以描述,所以所得的类图并不会反 映所有依赖关系,尽管这些依赖关系完全可以在u m l 中表示。这种简化表示对 于软件建模而言并无大碍,描述类接口的关系已经能很好地辅助设计和实现。但 对于单元测试而言,任何一个依赖未得以解决都会导致相关部分代码的不可测 试。因此,这种简化的类图就无法满足单元测试的需要。例如在上一节的例子中, d a t a m a l l a g c r 类在成员函数内部实现中对耽m 类和m e e t i i l g 类实例化,这种情况 很少会在u m l 类图中如图4 2 中一样描述,而如果单纯从接口和成员变量来观 察,三者之间的确不存在任何依赖关系。但对予单元测试而言,这种非接口上的 而实际存在的依赖关系却是不可忽略的。 a 暑e n d a a g e n d 鱼d a t a b 帖e d a t a 册瓤t a g e r 龆 啊e e t i n gi n it 酗e e t i n 葚 n r e g i s t e r r e c o r di n i t r e 菩i s t e r l 档 r e g is t e r r e c o r di n it r e g is t e r 2 oh n k e a l i = t q e c o r d d 怠t a b 毫兰e 矗。d a t 硼札a g e rd 毫t 硼毫n a g 甜 器si n t e g e r 工d no 工t e r a t o r q e c 盯d it 日“o r 嗣。d 趣t a 啊a n a g e ro 毒5 v o i di n i t 0 移3 b e c o r dg e t h e x t o 谚j ,o ida d d 啦e c o r ar e c o r d ) o5 y o i dd e l e t e ( ) o 。r e c o r dg e t 工n it r e c o r d0 彩) b 0 0 1 e a nh a s h e x t0 a g e n d a la 暑e n d a t i m e ,t i m e 蠡 i n t e g e ry e a r 叠工n t e 筘rm o n t h 。工n t e g e rd 夥 舒 i n t e g e rh o u r 谚。t i m e 0 i 。t i m e6 t r i n gs t r i n g ) 移。t i m 皂c r i m et i m e ) o ,o ias e t y e a r ( i n ty 薯 r ) 彩,o ids e t 朋o n t h ( i i l t 啊0 耵h ) i ds e t d 哆( i n td a t ) 静r o i ds e t h o u r ( i n tm u l l ) 葫b o o l e 姐e q u a l sc r i m e t i m e ) 叠s 乞r i n g0 1 i t p u t ( ) 0b 0 0 1 e a l nis b e o r ec r i m e t i m e ) 9b 0 0 1 e a ni 墨】炷t e rc r i 晴et i m e ) 图4 2 包含d a t a m a n a g e r 类和t i m e 类的u m l 类图 3 2 i ,山大学硕+ 学位论文 堆丁m 0 c ko 巧e c t 测试的契约小致错误的研究 找出所有依赖关系的另外一个途径是按照开发人员对引入包的声明来确定。 开发人员在对被测试类实现

温馨提示

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

最新文档

评论

0/150

提交评论