??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲欧洲日韩不卡,亚洲一级黄色大片,亚洲av产在线精品亚洲第一站http://www.tkk7.com/dearnnyang/archive/2006/02/22/31970.html阿兽学习(fn)阿兽学习(fn)Wed, 22 Feb 2006 06:58:00 GMThttp://www.tkk7.com/dearnnyang/archive/2006/02/22/31970.htmlhttp://www.tkk7.com/dearnnyang/comments/31970.htmlhttp://www.tkk7.com/dearnnyang/archive/2006/02/22/31970.html#Feedback0http://www.tkk7.com/dearnnyang/comments/commentRss/31970.htmlhttp://www.tkk7.com/dearnnyang/services/trackbacks/31970.html

如何q行单元试

作者:(x)葛志春(来源Q希赛网Q?nbsp; http://www.csai.cn  2003q?6?6?BR>
摘要Q?/STRONG>单元试是Y件测试的基础Q本文详l的了单元测试的两个步骤人工静态检查法与动态执行跟t法Q所需执行的工作项目及(qing)相关的策略和Ҏ(gu)。通过对这两个步骤的描qC者将多年的单元测试经验及(qing)试理论注入于全文?BR>
关键?单元试、h工检查、白盒测试、测试用例、跟t调?BR>
1 概述

单元试是针对Y件设计的最单位——程序模块,q行正确性检验的试工作。其目的在于发现每个E序模块内部可能存在的差错?BR>
单元试也是E序员的一基本职责,E序员必d自己所~写的代码保持认真负责的态度Q这是也E序员的基本职业素质之一。同时单元测试能力也是程序员的一基本能力,能力的高低直接媄响到E序员的工作效率与Y件的质量?BR>
在编码的q程中作单元试Q其p是最的Q而回报却特别优厚的。在~码的过E中考虑试问题Q得到的是更优质的代码Q因为在q时(zhn)对代码应该做些什么了解得最清楚。如果不q样做,而是一直等到某个模块崩溃了Q到那时(zhn)可能已l忘C代码是怎样工作的。即使是在强大的工作压力下,(zhn)也q必重新把它弄清楚Q这又要p许多旉。进一步说Q这样做出的更正往往不会(x)那么dQ可能更脆弱Q因为?zhn)唤回的理解可能不那么完全?BR>
通常合格的代码应该具备以下性质Q正性、清晰性、规范性、一致性、高效性等Q根据优先别排序)?BR>
1. 正确性是指代码逻辑必须正确Q能够实现预期的功能?BR>
2. 清晰性是指代码必ȝ明、易懂,注释准确没有歧义?BR>
3. 规范性是指代码必ȝ合企业或部门所定义的共同规范包括命名规则,代码风格{等?BR>
4. 一致性是指代码必d命名上(如:(x)相同功能的变量尽量采用相同的标示W)、风g都保持统一?BR>
5. 高效性是指代码不但要满以上性质Q而且需要尽可能降低代码的执行时间?BR>
2 单元试步骤

在代码编写完成后的单元测试工作主要分Z个步骤h工静态检查和动态执行跟t?BR>
人工静态检查是试的第一步,q个阶段工作主要是保证代码算法的逻辑正确性(量通过人工查发C码的逻辑错误Q、清晰性、规范性、一致性、算法高效性。ƈ可能的发现E序中没有发现的错误?BR>
W二步是通过设计试用例Q执行待程序来跟踪比较实际l果与预期结果来发现错误。经验表明,使用人工静态检查法能够有效的发?0%?0%的逻辑设计和编码错误。但是代码中仍会(x)有大量的隐性错误无法通过视觉查发玎ͼ必须通过跟踪调试法细心分析才能够捕捉到。所以,动态跟t调试方法也成了单元试的重点与隄?BR>
3 人工?/STRONG>

通常在h工检查阶D必L行以下项目的zdQ?BR>
W一?查算法的逻辑正确性;定所~写的代码算法、数据结构定义(如:(x)队列、堆栈等Q是否实C模块或方法所要求的功能?BR>
W二?模块接口的正性检查;定形式参数个数、数据类型、顺序是否正;定q回值类型及(qing)q回值的正确性?BR>
W三?输入参数有没有作正确性检查;如果没有作正性检查,定该参数是否的无需做参数正性检查,否则h加上参数的正性检查。经验表明,~少参数正确性检查的代码是造成软gpȝ不稳定的主要原因之一?BR>
W四?调用其他Ҏ(gu)接口的正性;查实参类型正与否、传入的参数值正与否、个数正与否,特别是具有多态的Ҏ(gu)。返回值正与否,有没有误解返回值所表示的意思。最好对每个被调用的Ҏ(gu)的返回值用显湿代码作正性检查,如果被调用方法出现异常或错误E序应该l予反馈Qƈd适当的出错处理代码?BR>
W五?出错处理Q模块代码要求能预见出错的条Ӟq设|适当的出错处理,以便在一旦程序出错时Q能对出错程序重做安排,保证光辑的正性,q种出错处理应当是模块功能的一部分。若出现下列情况之一Q则表明模块的错误处理功能包含有错误或缺P(x)出错的描q难以理解;出错的描qC以寚w误定位,不以确定出错的原因Q显C的错误信息与实际的错误原因不符Q对错误条g的处理不正确Q在寚w误进行处理之前,错误条g已经引vpȝ的干预等?BR>
W六?保证表达式、SQL语句的正性;查所~写的SQL语句的语法、逻辑的正性。对表达式应该保证不含二义性,对于Ҏ(gu)产生歧义的表辑ּ或运符优先U(如:(x)???》?&&、||?+?--{)可以采用扩号“(Q”运符避免二义性,q样一斚w能够保证代码的正可靠,同时也能够提高代码的可读性?BR>
W七?查常量或全局变量使用的正性;定所使用的常量或全局变量的取值和数倹{数据类型;保证帔R每次引用同它的取倹{数值和cd的一致性?BR>
W八?表示W定义的规范一致性;保证变量命名能够见名知意Qƈ且简z但不宜q长或过短、规范、容易记忆、最好能够拼诅Rƈ量保证用相同的表示W代表相同功能,不要不同的功能用相同的表示W表C;更不要用相同的表C符代表不同的功能意义?BR>
W九(ji)?E序风格的一致性、规范性;代码必须能保证符合企业规范,保证所有成员的代码风格一致、规范、工整。例如对数组做@环,不要一?x)儿采用下标变量从下C的方式(?for(I=0;I++QI<10)Q,一?x)儿又采用从上到下的方??for(I=10;I--;I>0))Q应该尽量采用统一的方式,或则l一从下CQ或则统一从上C。徏议采用for循环和W(xu)hile循环Q不要采用do{}while循环{?BR>
W十?查程序中使用到的秘数字是否采用了表C符定义。神U的数字包括各种常数、数l的大小、字W位|、变换因子以?qing)程序中出现的其他以文字形式写出的数倹{在E序源代码里Q一个具有原本Ş式的数对其本w的重要性或作用没提供Q何指C性信息,它们也导致程序难以理解和修改。对于这cȝU数字必采用相应的标量来表C;如果该数字在整个pȝ中都可能使用到务必将它定义ؓ(f)全局帔RQ如果该秘数字在一个类中用可其定义为类的属性(AttributeQ?如果该神U数字只在一个方法中出现务必其定义为局部变量或帔R?BR>
W十一?查代码是否可以优化、算法效率是否最高。如QSQL语句是否可以优化Q是否可以用1条SQL语句代替E序中的多条SQL语句的功能,循环是否必要Q@环中的语句是否可以抽出到循环之外{?BR>
W十二?查?zhn)的程序是否清晰简z容易理解。注意:(x)冗长的程序ƈ不一定不是清晰的?BR>
W十三?查方法内部注释是否完_(d)是否清晰z;是否正确的反映了代码的功能,错误的注释比没有注释更糟Q是否做了多余的注释Q对于简单的一看就懂的代码没有必要注释?BR>
W十四?查注释文档是否完_(d)对包、类、属性、方法功能、参数、返回值的注释是否正确且容易理解;是否?x)落了或多了某个参数的注释,参数cd是否正确Q参数的限定值是否正。特别是对于形式参数与返回g关于秘数值的注释Q如Q类型参?应该指出 1.代表什么,2.代表什么,3.代表什么等。对于返回结果集(Result Set)的注释,应该注释l果集中包含那些字段?qing)字D늱型、字D顺序等?BR>
4 动态执行跟t?/STRONG>

动态执行测试通常分ؓ(f)黑盒试与白盒测试。黑盒测试指已知产品的功能设计规|可以q行试证明每个实现了的功能是否W合要求。白盒测试指已知产品的内部工作过E,可以通过试证明每种内部操作是否W合设计规格的要求,所有内部成分是否已l经q检查?BR>
对于单元试来说主要应该采用白盒试法对每个模块的内部作跟踪查测试。对于单元白盒测试,应该对程序模块进行如下检查:(x)

1. Ҏ(gu)块内所有独立的执行路径臛_试一ơ;

2. Ҏ(gu)有的逻辑判定Q取“真”与“假”的两种情况都至执行一ơ;

3. 在@环的边界和运行界限内执行循环体;

4. 试内部数据的有效性等{?BR>
单元白盒跟踪试Q通常需要做如下三项工作:

1. 设计试用例Q?BR>
2. 设计试cL块;

3. 跟踪调试?BR>
4.1 试用例设计

通常动态执行跟t调试是在编码阶D进行的。在Ҏ(gu)E序作静态h工检查之后就可以开始进行单元测试的试用例设计。利用设计文档,设计可以验证E序功能、找出程序错误的多个试用例?BR>
4.1.1 试用例的设计基本原?BR>
设计试用例基本的原则是Q?BR>
1. 一个好的测试用例在于能够发现至今没有发现的错误Q?BR>
2. 试用例应由试输入数据和与之对应的预期输出l果q两部分l成Q?BR>
3. 在测试用例设计时Q应当包含合理的输入条g和不合理的输入条件?BR>
4.1.2 白盒试的测试用例设?BR>
白盒试试用例一般采用逻辑覆盖法和基本路径法进行设计?BR>
一、逻辑覆盖?/STRONG>

逻辑覆盖是以E序内部的逻辑l构为基的测试用例设计技术,q一Ҏ(gu)要求试人员对程序的逻辑l构有清楚的了解。逻辑覆盖可分为:(x)语句覆盖、判定覆盖、条件覆盖、判?条g覆盖、条件组合覆盖与路径覆盖?BR>
1. 语句覆盖是设计若干个测试用例,q行所程序,使得每一可执行语句至执行一ơ?BR>
2. 判定覆盖是设计若干个测试用例,q行所程序,使得E序中每个判断的取真分支和取假分支至经历一ơ?BR>
3. 条g覆盖是设计若干个测试用例,q行所程序,使得E序中每个判断的每个条g的可能取D执行一ơ?BR>
4. 判定--条g覆盖是设计_的测试用例,使得判断中每个条件的所有可能取D执行一ơ,同时每个判断的所有可能判断结果也臛_执行一ơ?BR>
5. 条gl合覆盖是设计_的测试用例,q行所程序,使得每个判断的所有可能的条g取值组合至执行一ơ?BR>
6. 路径试是设计_的测试用例,覆盖E序中所有可能的路径?BR>
每一U覆盖方法都有其优缺点,q?U覆盖方法关p,如图1Q?BR>


?

通常在设计测试用例时应该Ҏ(gu)代码模块的复杂度Q选择覆盖Ҏ(gu)。一般的代码的复杂度与测试用例设计的复杂度成正比。因此,设计人员必须做到模块或方法功能的单一性、高内聚性,使得Ҏ(gu)或函C码尽可能的简单;q样可大大提高?gu)试用例设计的容易度Q提高测试用例的覆盖E度?BR>
二、基本\径法

基本路径试法是在程序控制流囄基础上,通过分析控制构造的环\复杂性,导出基本可执行\径集合,从而设计测试用例的Ҏ(gu)。设计出的测试用例要保证在测试中E序的每个可执行语句臛_执行一ơ。基本\径测试法包括以下5个方面:(x)

1. E序的控制流图:(x)描述E序控制的一U图C方法?BR>
2. E序环境复杂性:(x)McCabe复杂性度量;从程序的环\复杂性可导出E序基本路径集合中的独立路径条数Q这是确定程序中每个可执行语句至执行依ơ所必须的测试用例数目的上界?BR>
3. 导出试用例?BR>
4. 准备试用例Q确保基本\径集中的每一条\径的执行?BR>
5. 囑Ş矩阵Q是在基本\径测试中赯助作用的软g工具Q利用它可以实现自动地确定一个基本\径集?BR>
另外Q对于测试用例的选择除了满所选择的覆盖程度(或覆盖标准)外还需要尽可能的采用边界值分析法、错误推法{常用地设计Ҏ(gu)。采用边界值分析法设计合理的输入条件与不合理的输入条gQ条件边界测试用例应该包括输入参数的边界与条件边界(if,whileQforQswitch ,SQL Where子句{)。错误推法Q列丑ևE序中所有可能的错误和容易发生错误的Ҏ(gu)情况Q根据它们选择试用例Q在~码、单元测试阶D可以发现很多常见的错误和疑似错误,对于q些错误应该作重Ҏ(gu)试,q设计相应的试用例?BR>
4.1.3 单元试计划表格

在设计测试用例时可以参考如下表|拟定Ҏ(gu)个类(或模块或?的测试计划。表1Q是Ҏ(gu)个类Q或模块或包Q作试计划的表_(d)它指明本试计划是针寚w个模块及(qing)相关文g的。表2是针对表1指定模块试用例而对应的子表Q每个测试用例可以拥有一个子表;单元试l果子表留作执行试用例时根据实际结果填写?BR>
子系l名. PackageName. JavaClassName

单元试计划
标识 格式Q?BR>
“子pȝ? jsp_filenameQ含目录中间用\分开卛_Q?

或?

“子pȝ? PackageName. JavaClassName?
lg功能?/TD> 如:(x)lg完成 “新增脓(chung)子”的功能
针对概要/详细设计文g?/TD> 如:(x)1.1版本公告部分详细设计说明?/TD>
物理文g?/TD> jsp_filenameQ含目录Q;

packageName. JavaClassName
?

单元试子项001

下面表格为针对上面表格“子pȝ? PackageName. JavaClassName”而对应的子表Q每个测试用例用一张子表:(x)

~号 .001 注:(x)? ~号?部分要从001~号开始一直到999Q个行编?/TD>
E序设计人员 如:(x)葛志?
试人员 如:(x)葛志?
试目的 如:(x)寚w误逻辑输入?
试内容描述 如:(x)对于public int fun3QString p1, int p2 Q的输入验,如果 p1 == null ,E序中检验到Q应该记录到pȝ logfile, return ?;
输入期望 P1 == null
功能处理期望描述 Logfile 多一条历史记录,Ҏ(gu)return -1Q?/TD>
输出期望 Return ?
单元试l果
实际输入数据 P1 = null
实际处理情况描述 E序没有q行p1 == null 的验证,没有?qing)时return ?Q而是q行?p1.aaa( ) Ҏ(gu)时出?null pointer 异常?/TD>
实际输出 没有?logfile 文gQ?/TD>
试l论 正常 / 异常
?

4.2 试c设?BR>
一个模块或一个方法(MethodQƈ不是一个独立的E序Q在考虑试它时要同时考虑它和外界的联p,用些辅助模块L拟与所模块相联系的其他模块。这些辅助模块分ZU:(x)

1. 驱动模块QdriverQ?相当于所模块的ȝ序。它接收试数据Q把q些数据传送给所模块,最后再输出实际试l果?BR>
2. 桩模块(stubQ?用于代替所模块调用的子模块。桩模块可以做少量的数据操作Q不需要把子模块所有功能都带进来,但不容许什么事情也不做?BR>
所模块与它相关的驱动模块?qing)桩模块共同构成了一个“测试环境”,如图2。驱动模块和桩模块的~写?x)给试带来额外的开销。因为它们在软g交付时不作ؓ(f)产品的一部分一同交付,而且它们的编写需要一定的工作量。特别是桩模块,不能只简单地l出“曾l进入”的信息。ؓ(f)了能够正的试软gQ桩模块可能需要模拟实际子模块的功能,q样桩模块的建立׃是很L了?/SPAN>



? 单元试的测试环?BR>
~写桩模块是困难Ҏ(gu)的,其实也是完全可以避免~写桩模块的Q只需在项目进度管理时实际桩模块的代码编写工作安排在被测模块前编写即可。而且q样可以提高?gu)试工作的效率,提高实际桩模块的试频率从而更有效的保证品的质量。但是,Z保证能够向上一层提供E_可靠的实际桩模块Qؓ(f)后箋模块试打下良好的基Q驱动模块还是必不可的?BR>
对于每一个包或子pȝ我们可以Ҏ(gu)所~写的测试用例来~写一个测试模块类来做驱动模块Q用于测试包中所有的待测试模块。而最好不要在每个cM用一个测试函数的Ҏ(gu)Q来试跟踪cM所有的Ҏ(gu)。这L(fng)好处在于Q?BR>
1. 能够同时试包中所有的Ҏ(gu)或模块,也可以方便的试跟踪指定的模块或Ҏ(gu)?BR>
2. 能够联合使用所有测试用例对同一D代码执行测试,发现问题?BR>
3. 便以回归试Q当某个模块作了修改之后Q只要执行测试类可以执行所有被的模块或方法。这样不但能够方便得查、跟t所修改的代码,而且能够查出修改对包内相x块或Ҏ(gu)所造成的媄响,使修改引q的错误得以?qing)时发现?BR>
4. 复用试Ҏ(gu)Qɋ试单元保持持久性,q可以用既有的测试来~写相关试?BR>
5. 测试代码与产品代码分开Q代码更清晰、简z;提高?gu)试代码与被代码的可维护性?BR>
4.3 跟踪调试

跟踪调试不但是深入测试代码的最x法,而且也是E序调试发现错误Ҏ(gu)的有利工兗?BR>
试c设计完成后Q最好能借助代码排错工具来跟t调试待代码段以深入的查代码的逻辑错误。现有的代码开发工P?JBuilderQ一般都集成了这cL错工兗排错工具一般由执行控制E序、执行状态查询程序、跟t程序组成。执行控制程序包括断点定义、断Ҏ(gu)销、单步执行、断Ҏ(gu)行、条件执行等功能。执行状态查询程序包括寄存器、堆栈状态、变量、代码等与程序相关的各种状态信息的查询。跟t程序用以跟t程序执行过E中所l历的事件序列(如:(x)分支、子E序调用{)。程序员可通过对程序执行过E中各种状态的判别q行E序错误的识别、定位及(qing)Ҏ(gu)?BR>
对于模块的单元跟t调试,最好能够做到对被测模块的每ơ修改,都对每个试用例q行跟踪执行一遍以排除所有可能出现或引进的错误。在旉有限的情况下也必调用驱动模块对所有的试用例执行一ơ,q对出现错误或异常的试用例跟踪执行一ơ,以发现问题的Ҏ(gu)?

排错q程往往是一个艰苦的q程Q特别是那种法复杂、调用子模块较多的模块,对于错误的定位来说ƈ不是一件容易的事情。尽排错不是一门好学的技术(有时Z更愿意称之ؓ(f)艺术Q,但还是有若干行之有效的方法和{略Q下面介l几U排错时应该采用的方法策略?BR>
1. 断点讄Q设|断点对源程序实行断点跟t将能够大大提高排错的效率。通常断点的设|除了根据经验与错误信息来设|外Q还应重点考虑以下几种c行的语句?BR>
1Q?函数调用语句。子函数的调用语句是试的重点,一斚w׃在调用子函数时可能引h口引用错误,另一斚w可能是子函数本n的错误?BR>
2Q?判定转移/循环语句。判定语句常怼(x)׃边界g比较优先U等问题引v错误或失效而作出错误的转移。因此,对于判定转移/循环语句也是一个重要的试炏V?BR>
3Q?SQL语句。对于数据库的应用程序来_(d)SQL语句常常?x)在模块中占比较重要的业务逻辑Q而且比较复杂。因此,它也属于比较Ҏ(gu)出现错误的语句?BR>
4Q?复杂法Dc(din)出错的概率怸法的复杂度成正比。所以越复杂的算法越需要作重点跟踪Q如递归、回朔等法?BR>
2. 可疑变量查看Q在跟踪执行状态下当程序停止在某条语句时可以查看变量的当前值和对象的当前属性。通过Ҏ(gu)q些变量当前g预期值可以轻杄定位E序问题Ҏ(gu)?BR>
3. SQL语句执行查,在跟t执行或q行状态下疑似错误的SQL语句打印出来Q重新在数据库SQL查询分析器(如:(x)Oracle SQL PlusQ中跟踪执行可以较高效的查纠正SQL语句错误?BR>
4. 注意集现象Q经验表明测试后E序中残存的错误数目与该E序中已发现的错误数目或错率成正比。根据这个规律,应当寚w误群集的E序D进行重Ҏ(gu)试,以提高测试投资的效益。如果发现某一代码D似乎比其他E序模块更多的错误們֐Ӟ则应当花费较多的旉和代h试这个程序模块?BR>


]]>
վ֩ģ壺 ھƷþþþӰԺ| ؼaƬëƬѿ| ĻѲ | ߹ۿƬaѹۿ| þþþAV鶹| Ƭ߹ۿѹۿȫ| ޱר| ɫè˳վ߹ۿ | ˳߹ۿվƷ| ޾Ʒxxx| þøݾƷԴվ| ޹a777 | ŮοaƬ| Ҹ| ѹۿëƬֻƵ| պƷרӰ| þþþŮۺ| ƬAëƬ| ޹Ѽһ| ѹۿŮˮƵ| պ޹ۺϸ| &#228;v뾫Ʒþþ | ޹Ʒ˿߹ۿ| ëƬѹۿƵȫ| Ƶ| ༤ۺ͵| һ234޿Ƶ| av뾫Ʒ| ӰԺ߹ۿ| 91avƵ߹ۿ| պһƷ侫| ˾Ʒձר61| þƵƷ| 鶹AVþþƷ| ޾ƷƷɫ| ͤͤѸ| ѹۿŮƵ| Aר߹ۿq| þþѸӰԺ| ձһ| AV뾫Ʒҹ.|