[转]Junit FAQ

如果是初次接触 Junit ,你或许有一大堆的疑问,这里根据网上的资料整理出了一些可以用来解除你的疑惑的问题列表......

【总结】Junit FAQ001-017

 

 

整理:wyingquan at hotmail dot com  时间:2005.02.25

原文:http://blog.csdn.net/wyingquan/

 

如果是初次接触Junit,你或许有一大堆的疑问,这里根据网上的资料整理出了一些可以用来解除你的疑惑的问题列表,我想对你是有用的:

001】没有人希望查看别人是如何设计测试类的。如果每个人都有不同的设计测试类的方法,光维护被测试的类就够烦了,谁还顾得上维护测试类?

Junit是一个回归测试框架,所谓框架就是他的作者Erich Gamma K ent Beck 定下了一些条条框框,你编写的测试代码必须遵循这个条条框框:继承某个类,实现某个接口。其实也就是我们前面所说的规范。好在JUnit目前得到了大多数软件工程师的认可。遵循JUnit我们会得到很多的支持。如果没有一定的规范,测试类的编写将会成为另一个需要定义的标准。

002】另外有一点我不想提,但是这个问题太明显了,测试类的代码多于被测试的类!这是否意味这双倍的工作?

不!1)不论被测试类的方法如何复杂,测试代码中的类的方法只会保持一样的代码量。2)提高软件的质量并解决软件熵这一问题并不是没有代价的。测试代码中的类就是代价。我们目前所能做的就是尽量降低所付出的代价:我们编写的测试代码要能被维护人员容易的读取,我们编写测试代码要有一定的规范。

003】什么是软件熵?

有一个聪明人提出了软件熵(software entropy)的概念:一个程序从设计很好的状态开始,随着新的功能不断地加入,程序逐渐地失去了原有的结构,最终变成了一团乱麻。

004】怎么样编写的测试代码才能真正发现问题?

要注意编写一定能通过的测试代码(如以前举的例子)并没有任何意义,只有测试代码能帮助我们发现bug,测试代码才有其价值。此外测试代码还应该对工作代码进行全面的测试。如给方法调用的参数传入空值、错误值和正确的值,看看方法的行为是否如你所期望的那样。可以在网上搜索别人总结的一些经验。

005】什么是断言?

断言是一个布尔语句,该语句不能为假,如果为假,则表明出现了一个bug。我是在使用Jmeter时知道这个词语的,当时还纳闷这个词什么意思?使用RationalMI公司自动化测试工具的人一定知道其中的一个术语“检查点”(或称为验证点),我们可以把断言理解为检查点或验证点。

注:以下006-013摘自人民邮电出版社出版王东刚编著的《软件测试与Junit实践》一书,该书最大的特点在于“学以致用”,是作者经验的积累,推荐阅读。

006】白盒测试用例应该怎么写?

不管哪种测试用例,都不可避免地再内容中涉及到三类数据:正常数据、边界值和错误数据。由于执行测试用例的数量巨大以及还要进行回归测试,所以必须使用自动化测试工具,但提取测试数据仍要依靠编写测试用例人员的经验。

007】类测试和传统单元测试有什么区别?

类测试和传统测试略有不同,这是由于类的构造和其实现方式的特殊性造成的,所以对类的测试更为复杂。传统单元测试注重单元之间的接口测试,也就是说每个单元都有自己的输入输出接口,在调用中如果出现了严重错误,那么这些错误也事因为单元之间接口的实现引发的,和单元本身并没有什么直接关系。

而在面向对象的世界里,每一个类就是一组最小的交互单元,其内部封装了各种属性和消息传递方式。类被实例化后产生了对象,每个对象都有相对的声明周期和活动范围,在这个范围内,类测试除了测试类中包含的类方法,还要测试类的状态,这是传统单元测试所没有的。

008】类的测试用例需要注意什么?

类的测试用例需要确保类实例完全满足类的设计描述,对某个类进行测试除了要确保它能实现预定的设计外,还要关注这个类和其它类之间的特殊关系(可能是关联、是实现或者是依赖于等),如果类的测试用例只能覆盖优先的实现单元,则降低了整个测试用例的有效执行过程,或者需要投入更多的资源制作更多的测试用例来测试类,后期的测绘用例维护也是非常困难的。

009】类的测试过程是怎么样的?

测试驱动驱动盖该类的测试用例,根据测试用例的指定情况生成用例所需要的测试环境和实例。在这个测试环境中,测试驱动向实例发送一个或者多个需验证消息,然后根据实例状态变化、响应值、返回参数和结果,来判断验证消息是否通过。在所有测试用例验证项目执行后,测试驱动释放所有的已生成的实例和值域。

如果类包含了静态属性或者静态方法,同样需要对其进行测试。这些静态属性和方法属于类本身,表明该类本身就是个对象,无须实例化就可以直接调用这些属性和方法。

010】类需要测试到什么程度?

类的测试程度取决于测试了多少类实现和类描述,并且不同类的测试程度估算比较困难,比如接口类中包含了1组方法,有个具体类实现了它,我们在具体类的测试用例中加入了该接口方法的测试,如果该具体类的其他实例方法没有和任何类交互,那么改类的测试覆盖率就是100%。每个类被实例化后都有自己的状态,状态影响操作的具体含义。对于任何一个类进行测试都需要进行综合考虑,穷举是一种无效率的工作方法,我们可以采用组合测试或者在多个测试用例中抽取重要的、覆盖面最大的测试用例执行测试。

011】如何确定类测试用例?

类测试用例的确定和构造取决于准确的类描述,而类描述可能包含类UML设计、类CRC卡片和类状态机等工作。在类测试中介入了两种工作角色(设计人员和实现人员),这样避免了实现人员在类实现期间因误解了类描述,而将错误带入测试用例中,造成测试不准确或者测试失效现象。如果类没有匹配的描述工作,请设计人员不上,虽然可以采用“逆向工程”导出类描述,但是这样的类描述是欠缺的。

1、根据前置和后置状态确定测试用例

测试用例根据前置和后置条件来确定,其具体实现形式为各个测试方法体,并且在前置条件中指定输入值(包括常见值和边界值)来增加测试用例的测试覆盖率,每一个测试用例都可以包含特殊的前置条件(即错误前置条件)来观察测试用例失败后的异常处理机制是否正确。根据类描述得出测试用例的前置和后置条件,并且根据前置和后置条件的不同组合方式产生不同的测试用例具体测试方法体。

2、根据状态转换确定测试用例

很多人习惯用状态转换图来确定测试用例而不是根据测试用例的前置条件和后置状态,在状态图中类关联行为明显很容易被测试者辨别,但是这同样要求测试这需要设定更多的特殊值验证类关联关系(例如使用极端的输入值引起了补课预料的状态崩溃),并且使用状态转换图很难确定所有的测试用例。

3、根据代码确定测试用例

012】如何构造类测试驱动?

RUP中测试的概念是测试优先于设计,而在XP中则表现为测试优先于编程。测试驱动的基本思想就是在对设计(或编码)之前先考虑好(或写好)测试代码,这样,测试工作就不仅仅是测试,而成为设计(或代码)的规范了。

类测试驱动器是运新干一个或者多个测试用例的可执行程序,编写类测试驱动有三种方法,分别是(1)调用Main方法、嵌入静态测试方法和实现独立测试类。(2)在类种嵌入静态测试方法,通过调用该测试方法来收集每个测试用例的执行结果。(3)实现独立的测试类。3种类测试驱动的编写方法在执行测试用例和获取执行后测试结果的效果是一样的,建议使用第三种测试驱动编写方式。

013】类的测试方式有哪些?

类有三种不同的测试方式:

1、功能测试接口:测试用例根据类描述确定;

2、构造测试接口:测试用例着重测试类的构造(类可能包含多条构造方法);

3、交互测试接口:测试用例测试发送消息对一个对象的操作是否正确。

确定这些测试接口是为了后续维护的方便,它也体现了我们遵循何种规则来确定测试用例,并且关系到类的变化对测试用例的影响,表现了使用TestCase的行为实现。

如果类在具体实例化过程种出现了变化,那么就需要调整对应的测试驱动程序。

014Junit常用的接口和类

1Test接口:运行测试和收集测试结果;

2TestCase抽象类:定义测试中固定方法;

TestCaseTest接口的抽象实现(不能被实例化,只能被继承)

3Assert静态类:一系列断言方法的集合;

4TestSuit测试包类:多个测试的组合

TestSuit类负责组装多个TestCase,待测得类中可能包括对被测类的多个测试,而TestSuit负责收集这些测试,使我们可以在一个测试中,完成全部的对被测类的多个测试。

补充:一个测试成为TestCase(测试用例),而一组TestCase构成Testsuite(测试套件)。

015Junit编写测试类的基本步骤:

1>扩展TestCase类;

2>覆盖runTest()方法(可选);

3>写一些testXXXXX()方法;

016Junit一些具体的编写测试代码的技巧或较好的实践方法:

1.不要用TestCase的构造函数初始化Fixture,而要用setUp()tearDown()方法。

2.不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。

3.避免编写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,就不要提交交易数据。简单的会滚就可以了。

4.当继承一个测试类时,记得调用父类的setUp()tearDown()方法。

5.将测试代码和工作代码放在一起,一边同步编译和更新。(使用Ant中有支持junittask.

6.测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。

7.确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。

8.如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。

9.尽可能地利用JUnit提供地assert/fail方法以及异常处理的方法,可以使代码更为简洁。

10.测试要尽可能地小,执行速度快。

 

017

junit的使用并不很难,然而要书写一个好的TestCase却并非易事。一个不好的TestCase往往是既浪费了时间,也起不了实际的作用。相反,一个好的TestCase,不仅可以很好的指出代码中存在的问题,而且也可以作为代码更准确的文档,同时还在持续集成的过程中起非常重要的作用。在此给出书写TestCase时需要注意的几点:

-          测试的独立性:一次只测试一个对象,方便定位出错的位置。这有2层意思:一个TestCase,只测试一个对象;一个TestMethod,只测试这个对象中的一个方法。

-          给测试方法一个合适的名字

-          assert函数中给出失败的原因,如:assertTrue( “… should be true”,  ……),方便查错。在这个例子中,如果无法通过assertTrue,那么给出的消息将被显示。在junit中每个assert函数都有第一个参数是出错时显示消息的函数原型。

-          测试所有可能引起失败的地方,如:一个类中频繁改动的函数。对于那些仅仅只含有getter/setter的类,如果是由IDE(如Eclipse)产生的,则可不测;如果是人工写,那么最好测试一下。

-          setUptearDown中的代码不应该是与测试方法相关的,而应该是全局相关的。如针对与测试方法AB,在setUptearDown中的代码应该是AB都需要的代码。

-          测试代码的组织:相同的包,不同的目录。这样,测试代码可以访问被测试类的protected变量/方法,方便测试代码的编写。放在不同的目录,则方便了测试代码的管理以及代码的打包和发布。一个例子如下:

src   <=源代码根目录
 |---com
     |---mod1
         |---class1
junit   <=
测试代码根目录
 |---com
     |---mod1
         |---class1

 

 

整理:wyingquan at hotmail dot com  时间:2005.02.25

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值