junit实例教程
上一篇 / 下一篇 2012-11-01 10:52:56 / 个人分类:UnitTest
1、概述51Testing软件测试网[3v)w;Hm)}3[)@
Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。
d:lb9^D7M"x`W0 Junit本质上是一套框架,即开发者制定了一套条条框框,遵循这此条条框框要求编写测试代码,如继承某个类,实现某个接口,就可以用Junit进行自动测试了。51Testing软件测试网xw%iy,c!zo
由于Junit相对独立于所编写的代码,可以测试代码的编写可以先于实现代码的编写,XP 中推崇的 test first design的实现有了现成的手段:用Junit写测试代码,写实现代码,运行测试,测试失败,修改实现代码,再运行测试,直到测试成功。以后对代码的修改和优化,运行测试成功,则修改成功。
"f
CHT.X0 Java 下的 team 开发,采用 cvs(版本控制) + ant(项目管理) + junit(集成测试) 的模式时,通过对ant的配置,可以很简单地实现测试自动化。51Testing软件测试网h
wI e lU:T%m*d
对不同性质的被测对象,如Class,Jsp,Servlet,Ejb等,Junit有不同的使用技巧,以后慢慢地分别讲叙。以下以Class测试为例讲解,除非特殊说明。51Testing软件测试网'F~B0{ T2X Gp0f
2、下载安装51Testing软件测试网,p+agG'N}
51Testing软件测试网\n
m,Hg9e
- 去Junit主页下载最新版本3.8.1程序包junit-3.8.1.zip
~mt.{S'e+CEQ0 - 用winzip或unzip将junit-3.8.1.zip解压缩到某一目录名为$JUNITHOME51Testing软件测试网Dhy(]j
Y
S!n1v
- 将junit.jar和$JUNITHOME/junit加入到CLASSPATH中,加入后者只因为测试例程在那个目录下。51Testing软件测试网Zh$ra"G7Gucz
- 注意不要将junit.jar放在jdk的extension目录下51Testing软件测试网Xa0?T2z Hf5a\G
- 运行命令,结果如右图。java junit.swingui.TestRunner junit.samples.AllTests
51Testing软件测试网,`mIbm]e.Jp
3、Junit架构51Testing软件测试网'ZZnUf%U
下面以Money这个类为例进行说明。
private int fAmount;//余额
rQ/Sv9PL:w*x]0 private String fCurrency;//货币类型
51Testing软件测试网#MP(q`,N
public Money(int amount, String currency) {51Testing软件测试网3g,uxPTZ*{L
fAmount= amount;51Testing软件测试网+@Q \s#},b#l[
fCurrency= currency;51Testing软件测试网} ~7t)r;|
}51Testing软件测试网 v1f8H$Zc,h
S
V#G
public int amount() {51Testing软件测试网(];Y5sW*VI,W8t'nD^1{9f
return fAmount;
?+^b%Jge0 }51Testing软件测试网2W0y Y`P
public String currency() {51Testing软件测试网x4gDsn
return fCurrency;
qG7y)T PB0 }
k2F3l8wfC;M'y0 51Testing软件测试网o PKFs d4O(J*_)B:H
public Money add(Money m) {//加钱
#H,i%W7d.k0 return new Money(amount()+m.amount(), currency());
4j/YO(R D4WG'b0 }51Testing软件测试网L b(]+l)Q@L+F`:tt2HI
5}*Ja+mi&y'yr0 public boolean equals(Object anObject) {//判断钱数是否相等51Testing软件测试网.t.lM2l1?Z;m
|0S
if (anObject instanceof Money) {
lUg!n9C0 Money aMoney= (Money)anObject;51Testing软件测试网NW b1ju'gV
return aMoney.currency().equals(currency())
Dr9}0d@0 && amount() == aMoney.amount();
.z"EAFLR Kc'|d7kk0 }
,p5_Q3i'E?3h0 return false;51Testing软件测试网3je q9X~l!l
}
zJJ7dRN$o,c0}51Testing软件测试网i4I8mnp)m+]
Junit本身是围绕着两个设计模式来设计的:命令模式和集成模式.
- 命令模式51Testing软件测试网c,jPDZ]w ?
利用TestCase定义一个子类,在这个子类中生成一个被测试的对象,编写代码检测某个方法被调用后对象的状态与预期的状态是否一致,进而断言程序代码有没有bug。
1`O.TS\ETk0 当这个子类要测试不只一个方法的实现代码时,可以先建立测试基础,让这些测试在同一个基础上运行,一方面可以减少每个测试的初始化,而且可以测试这些不同方法之间的联系。
hd}*IgY n0 例如,我们要测试Money的Add方法,可以如下:public class MoneyTest extends TestCase { //TestCase的子类51Testing软件测试网CzT+A S h(Z
O3X@:NYlel)A]0 public void testAdd() { //把测试代码放在testAdd中51Testing软件测试网 m9QyM-Lgczz
Money m12CHF= new Money(12, "CHF"); //本行和下一行进行一些初始化
.A5[-\)] f5~ G%j0 Money m14CHF= new Money(14, "CHF"); 51Testing软件测试网4Uk5A,X%\R
Money expected= new Money(26, "CHF");//预期的结果
8Fex\ o8}7rS$Z|3Pf,Q0 Money result= m12CHF.add(m14CHF); //运行被测试的方法51Testing软件测试网MO g1J w
Assert.assertTrue(expected.equals(result)); //判断运行结果是否与预期的相同
RS:?z3S}*J~0 }
GWh4w!w:[0}
如果测试一下equals方法,用类似的代码,如下:public class MoneyTest extends TestCase { //TestCase的子类51Testing软件测试网5Ik ?G@,Xo
public void testEquals() { //把测试代码放在testEquals中
6s~4j z)W*WO6e#E0 Money m12CHF= new Money(12, "CHF"); //本行和下一行进行一些初始化51Testing软件测试网je{C%U5a4N'i3l
Money m14CHF= new Money(14, "CHF");51Testing软件测试网 w-~fJ,[$qoF
Assert.assertTrue(!m12CHF.equals(null));//进行不同情况的测试
X,g1E D vD0
"o;TB$WZEf0 Assert.assertEquals(m12CHF, m12CHF);
O m-C:DnH0 Assert.assertEquals(m12CHF, new Money(12, "CHF")); // (1)51Testing软件测试网X]5X]n'DA,^H
Assert.assertTrue(!m12CHF.equals(m14CHF));51Testing软件测试网&N%@ o?)g \hao
}51Testing软件测试网Ps[7xo9Z!JDS7O
}
,X'F d%[VEGS0 当要同时进行测试Add和equals方法时,可以将它们的各自的初始化工作,合并到一起进行,形成测试基础,用setUp初始化,用tearDown清除。如下:public class MoneyTest extends TestCase {//TestCase的子类51Testing软件测试网U"Oz l-u T)[;W51Testing软件测试网,\Vq7El9f3jz
private Money f12CHF;//提取公用的对象51Testing软件测试网Ej[*p.W
private Money f14CHF;51Testing软件测试网 e{ LT`:W
protected void setUp() {//初始化公用对象51Testing软件测试网ic:P:S+^ lh
Z:G_M LOa0
f12CHF= new Money(12, "CHF");
L)pU#B/[0 f14CHF= new Money(14, "CHF");51Testing软件测试网K)aE"cvR
}
c,lirZ"m0 public void testEquals() {//测试equals方法的正确性
-w(Re?Y"F0 Assert.assertTrue(!f12CHF.equals(null));
_js5?4l:D`0 Assert.assertEquals(f12CHF, f12CHF);51Testing软件测试网^o+a.}1g/H0n8obi
Assert.assertEquals(f12CHF, new Money(12, "CHF"));51Testing软件测试网 q3o ZN L~ u[Rd
Assert.assertTrue(!f12CHF.equals(f14CHF));
2?z!ss_ xN0 }
(n.n3[9~9A0]9Z0 51Testing软件测试网 o0h0l'n M$T;P
public void testSimpleAdd() {//测试add方法的正确性
GsM3WZ2N}0 Money expected= new Money(26, "CHF");51Testing软件测试网4cH{X7Us+BW^
Money result= f12CHF.add(f14CHF);51Testing软件测试网 |!Yh gK4p_
Assert.assertTrue(expected.equals(result));
-_,e ?){i6Wn0 }51Testing软件测试网2L mw1]7Z}5A
}
将以上三个中的任一个TestCase子类代码保存到名为MoneyTest.java的文件里,并在文件首行增加import junit.framework.*;,都是可以运行的。关于Junit运行的问题很有意思,下面单独说明。51Testing软件测试网;?5Rm cUw
上面为解释概念“测试基础(fixture)”,引入了两个对两个方法的测试。命令模式与集成模式的本质区别是,前者一次只运行一个测试。
q5f&I8v{O#G1`L0 - 集成模式
%Z%K~ \E Eh]B0 利用TestSuite可以将一个TestCase子类中所有test***()方法包含进来一起运行,还可将TestSuite子类也包含进来,从而行成了一种等级关系。可以把TestSuite视为一个容器,可以盛放TestCase中的test***()方法,它自己也可以嵌套。这种体系架构,非常类似于现实中程序一步步开发一步步集成的现况。51Testing软件测试网I'^a9C3|5SRD
对上面的例子,有代码如下:public class MoneyTest extends TestCase {//TestCase的子类
N#T,f.nT:T$C0n0 ....
YVDL3q;JeK0 public static Test suite() {//静态Test