一、简介
JUnit是一个开源的java单元测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例(用于java语言)。在1997年,由 Erich Gamma 和 Kent Beck 开发完成。这两个牛人中 Erich Gamma 是 GOF 之一;Kent Beck 则在 XP 中有重要的贡献。
JUnit设计的非常小巧,但是功能却非常强大。
下面是JUnit一些特性的总结:
1、用于测试期望结果的断言(Assertion)
2、用于共享共同测试数据的测试工具
3、用于方便的组织和运行测试的测试套件
4、图形和文本的测试运行器
2、用于共享共同测试数据的测试工具
3、用于方便的组织和运行测试的测试套件
4、图形和文本的测试运行器
对不同性质的被测对象,如Class,Jsp,Servlet,Ejb等,Junit有不同的使用技巧。
以下仅以Class测试为例
需要说明的是junit一般是用来进行单元测试的,因此需要了解被测试代码的内部结构(即所谓的白盒测试),另外junit是在xp编程和重构(refactor)中被极力推荐使用的工具,因为在实现自动单元测试的情况下可以大大的提高开发的效率,但是实际上编写测试代码也是需要耗费很多的时间和精力的
使用它的好处是:
1、对于xp编程而言,要求在编写代码之前先写测试,这样可以强制你在写代码之前好好的思考代码(方法)的功能和逻辑,否则编写的代码很不稳定,那么你需要同时维护测试代码和实际代码,这个工作量就会大大增加。因此在xp编程中,基本过程是这样的:构思-》编写测试代码-》编写代码-》测试,而且编写测试和编写代码都是增量式的,写一点测一点,在编写以后的代码中如果发现问题可以较块的追踪到问题的原因,减小回归错误的纠错难度
2、对于重构而言,其好处和xp编程中是类似的,因为重构也是要求改一点测一点,减少回归错误造成的时间消耗。
3、对于非以上两种情况,我们在开发的时候使用junit写一些适当的测试也是有必要的,因为一般我们也是需要编写测试的代码的,可能原来不是使用的junit,如果使用junit,而且针对接口(方法)编写测试代码会减少以后的维护工作,例如以后对方法内部的修改(这个就是相当于重构的工作了)。另外就是因为junit有断言功能,如果测试结果不通过会告诉我们那个测试不通过,为什么,而如果是想以前的一般做法是写一些测试代码看其输出结果,然后再由自己来判断结果使用正确,使用junit的好处就是这个结果是否正确的判断是它来完成的,我们只需要看看它告诉我们结果是否正确就可以了,在一般情况下会大大提高效率。
JUnit框架组成
l 对测试目标进行测试的方法与过程集合,可将其称为测试用例。(TestCase)
2 测试用例的集合,可容纳多个测试用例(TestCase),将其称作测试包。(TestSuite)
3 测试结果的描述与记录。(TestResult)
4 测试过程中的事件监听者 (TestListener)
5 每一个测试方法所发生的与预期不一致状况的描述,称其测试失败元素。(TestFailure)
6 JUnit Framework中的出错异常。(AssertionFailedError)
二、下载
点击/可以下载到最新版本的JUnit,本文使用的为3.8.1版。至于安装或者配置之类,你只需要轻松的将下载下来的压缩包中的jar文件,放到你工程的classpath中就可以了。
三、使用
按照框架规定:编写的所有测试类,必须继承自junit.framework.TestCase类;里面的测试方法,命名应该以Test开头,必须是public void 而且不能有参数;而且为了测试查错方便,尽量一个TestXXX方法对一个功能单一的方法进行测试;使用assertEquals等junit.framework.TestCase中的断言方法来判断测试结果正确与否。
而且你在这个测试类中有加入多少个测试方法,就会运行多少个测试方法
简单例子:
这是一个只会做两数加减的超级简单的计算器(小学一年级必备极品)。代码如下:
public class SampleCalculator
{
public int add(int augend , int addend)
{
return augend + addend ;
}
public int subtration(int minuend , int subtrahend)
{
return minuend - subtrahend ;
}
}
将上面的代码编译通过。下面就是我为上面程序写的一个单元测试用例:
//请注意这个程序里面类名和方法名的特征
public class TestSample extends TestCase
{
public void testAdd()
{
SampleCalculator calculator = new SampleCalculator();
int result = calculator.add(50 , 20);
assertEquals(70 , result);
}
public void testSubtration()
{
SampleCalculator calculator = new SampleCalculator();
int result = calculator.subtration(50 , 20);
assertEquals(30 , result);
}
}
看上面的代码的时候,是不是注意到每个TestXXX方法中都有一条SampleCalculator初始化语句?这很明显不符合编码规范。你可能正要将它提取出来放到构造函数里面去。且慢!在
JUnit中的初始化是建议在Setup方法中作的。JUnit提供了一对方法,一个在运行测试方法前初始化一些必备条件而另一个就是测试完毕后去掉初始化的条件(见下图)。
运行结果
如果错误则会显示红条
注意Errors和Failures的不同含义
Failures作为单元测试所期望发生的错误,它预示你的代码有bug,不过也可能是你的单元测试代码有逻辑错误(注意是逻辑错误)。Errors不是你所期待的,发生了Error你可以按照
下面的顺序来检查:
检查测试所需的环境,如:数据库连接
检查单元测试代码
检查你的系统代码
如果正确则会显示绿条
四、总结
J-Unit测试建议
以下是对JUnit实践的一个很好的总结
1、针对接口测试,不要针对实现。
2、每次只对一个接口进行UT测试(unit-test one object at a time)。这样能使你尽快发现问题,而不被各个对象之间的复杂关系所迷惑。
3、给测试方法起个好名字(choose meaningful test method names)。应该是用形如testXXXYYY(),这样的格式来命名你的测试方法。前缀test是用java编写一个简单的计算器Junit查测试方法的依据,XXX应该是你测试的方法名,YYY应该是你测试的状态。当然如果你只有一种状态需要测试可以直接命名为testXXX()。
4、明确写出出错原因(explain the failure reason in assert calls)。在使用assertTrue,assertFalse,assertNotNull,assertNull方法时,应该将可能的错误的描述字符串,以第一个参数传入相应的方法。这样你可以迅速的出出错原因。
5、一个UT测试方法只应该测试一种情况(one unit test equals one testMethod)。一个方法中的多次测试,只会混乱你的测试目的。
6、测试任何可能的错误(test anything that could possibly fail)。你的测试代码不是为了证明你是对的,而是为了证明你没有错。因此对测试的范围要全面,比如边界值、正常值、错误值;对代码可能出现的问题要全面预测。
底层dao层只作正确查询,验证正确即可,对于高层业务层如bd层,façade层,重点在错误数据查询
7、让你的测试帮助改善你的代码(let the test improve the code)。测试代码永远是我们代码的第一个用户,所以不仅让他帮组我们发现Bug,还要帮组我们改善我们的设计,就是有名的测试驱动开发(Test-Driven Development,TDD)。
8、一样的包,不同的位置(same package, separate directories)。测试的代码和被测试的代码应该放到不同的文件夹中,建议使用这种目录 src/java/代码 src/test/测试代码。 这样可以让两份代码使用一样的包结构,但是放在不同的目录下。
9、关于setup与teardown
a) 不要用TestCase的构造函数初始化Fixture,而要用setUp()和tearDown()方法。
b) 在setUp和tearDown中的代码不应该是与测试方法相关的,而应该是全局相关的。如:针对与测试方法都要用到的数据库链接等等。
c) 当继承一个测试类时,记得调用父类的setUp()和tearDown()方法。
10、不要在mock object中牵扯到业务逻辑(don’t write business logic in mock objects)。
11、只对可能产生错误的地方进行测试(only test what can possibly break)。如:一个类中频繁改动的函数。对于那些仅仅只含有getter/setter的类,如果是由IDE(如Eclipse)产生的,则可不测;如果是人工写,那么最好测试一下。
12、尽量不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。
13、避免编写有副作用的TestCase,你要确信保持你的测试方法之间是独立的。
14、将测试代码和工作代码放在一起,一边同步编译和更新(使用Ant中有支持junit的task)。
15、确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
16、如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论