我的地盘我做主! 博客:http://tester2test.cnblogs.com/   msn:win_soft@163.com

使用NUnit在.Net编程中进行单元测试

上一篇 / 下一篇  2007-07-12 12:19:40 / 个人分类:其他

本文通过一个详实的例子,详细介绍了如何在C#中利用NUnit单元测试框架进行应用程序类的单元测试工作。
W [4[~hS+Y#i s`0
O+UsP(\F"lP7P0
P7R.S9M*M0引言:51Testing软件测试网?t#Lud:WUG6h \w%i
举一个可能会发生在你身边的事件将更能贴近实际,幸好我们现在就有一件在程序员看来非常普通的任务:
"K#E5KW W*|?3m0你今天第一天上班,你的项目经理拿给你一叠不算厚的文档,告诉你今天的任务是按照文档中的要求编写一个.Net类,可能因为任务并不复杂,所以他看上去非常的随意。
"|:aB2K/f3R0今天能否很好的完成任务对你来说非常特殊,你拿过来后快速略过了前面大段的项目介绍,因为你知道那些对你并不重要,印象中好象是一个关于售票系统的工程。很快,你找了你需要关注的重点:类的需求说明文档。你详细的看了一遍,感觉并不复杂,类名Ticket,有一个只读的int型公共的属性,名称是Amount,还有两个方法,一个是名称是Sell,功能是将Amount减去一,表示卖掉了一张票,当然,票可不能为负数,如果是的话,抛出一个异常说明原因。另一个是Add,它有一个int型的参数,功能是将这个参数的值加到Amount中去,可能是表示进票之类的事情吧,你不太关心,反正这个程序很简单,你掩饰住内心的狂喜,打开电脑,调出编辑器,开始准备写程序了。
#A/U CL.A8T:R6e4i0"喂,等等",项目经理不知道什么时候又转回来了,"我想知道你打算怎么进行单元测试,我最关心的是这个"。
:I? L2whPd(N]J0"什么是单元测试?"你转过头一脸沮丧的看着失望的项目经理。51Testing软件测试网/DW/r `1da)u
51Testing软件测试网6G.Gmh"{;NY fN
--------------------------------------------------------------------------------
!]"Y"eT%yY.S051Testing软件测试网 i_m.|D7@nz
什么是单元测试:
7brwi9FI,My*dV0在程序设计过程中会有许多种测试,单元只是其中的一种,单元测试并不能保证程序是完美无缺的,但是在所有的测试中,单元测试是第一个环节,也是最重要的一个环节。单元测试是一种由程序员自行测试的工作。简单点说,单元测试就是测试代码撰写者依据其所设想的方式执行是否产生了预期的结果。关于单元测试的重要性已经有许多文章做了很多深入的分析,这里就不再赘述。51Testing软件测试网/I3F B\"b-Bn _'K
NUnit是一个为Net准备的自动化单元测试框架,它的作用就是帮助你方便的完成单元测试工作,同鼎鼎有名的JUnit一样,都是xUnit家族的成员。它的下载地址是:http://www.nunit.org
"Z7s`l'kGq0
,Y%Do*GaKd E$I0--------------------------------------------------------------------------------51Testing软件测试网 F2wF.qRK_
51Testing软件测试网!E`!r XEH5T'e
测试先行:
:D g'm,|8AG^*b0U0"什么?先写测试?"你一定非常惊讶,对!就是先来编写测试代码,按照极限编程(XP)的理论,写测试就是对软件进行设计的过程,它的重要性甚至超过了实际完成功能的代码。先将测试写完,然后再来完成代码,这样,所有的测试通过之日也就是程序完成之时。51Testing软件测试网*WT_,n)i$P:wM
首先,我们将NUnit提供的要nunit.framework.dll文件引入到工程中,并创建一个名为TicketTest的类:51Testing软件测试网!k3{8Y-\5Jhh
[TestFixture]
n/Rqq/@j0        public class TicketTest51Testing软件测试网TE#j'B*cRc(n cs
        {
)I6Z Q"Oa0                [Test]51Testing软件测试网qvB'^XX%e R
                public void Add()
O4xw G&cH&o*k0                {
mM+SV\M;Od/s0                        Ticket ticket = new Ticket();
1CV:kU i!h2D*q R,P0                        ticket.Add(100);51Testing软件测试网ZbY*B,h
                        Assertion.AssertEquals(100, ticket.Amount);51Testing软件测试网+~!|7f s#{F8d4f
                }51Testing软件测试网S Q$y.H#n
        }
MpHL0F:EX N-nNn/q0
"a/@+P6Tn J0注意,其中的[TestFixture]和[Test]两个Attribute为NUnit所规定必须要添加的,这样,测试框架就可以知道哪些类或者方法需要进行测试。51Testing软件测试网q1^3U_Z+ywH T u#C
我们在Add方法中定义了一个ticket对象,并给他加了100张票,然后就可以使用:
i:X/|`M2z0Assertion.AssertEquals(100, ticket.Amount);51Testing软件测试网0~8b KV*y"|L0\y
来测试ticket的Amount属性是否确实为100。
d9V V3g-H8}@0接下来,我们再向TicketTest中添加一个测试Sell的方法:
O1Kd"uc0[Test]
)T \2P f*@C0                public void Sell()
$^.q5YP(x7t)B0                {
f%\ur(f@9J0                        Ticket ticket = new Ticket();51Testing软件测试网}k:Wi"y&[
                        ticket.Add(100);
8W:w#|%da,h0                        ticket.Sell();51Testing软件测试网.w;mpBc @BA
                        ticket.Sell();51Testing软件测试网[;Oi4okf0XA+B
                        ticket.Sell();51Testing软件测试网btZ k$]mhCI
                        Assertion.AssertEquals(97, ticket.Amount);51Testing软件测试网Bx(_0y-m ]?]h
                }
OP0dl\G5?p051Testing软件测试网,{Ef7p1Y*nf C}
这里,我们先加了100张票之后就一口气卖掉了3张,然后看看我们是否还剩下97张票。
;lzNeY/k"rt0好了,这两个方法的测试已经做完了,我们来看一下测试的结果,根据要求,我们写了如下代码:51Testing软件测试网&kX yBe^8c
public class Ticket51Testing软件测试网$H5L#~"@A"dWD
        {51Testing软件测试网"d z8S^/G
                private int amount;51Testing软件测试网'T2Mt1t5e5H
                public int Amount51Testing软件测试网IWVEVz
                {51Testing软件测试网C3R'EEU r*^]:s
                        get51Testing软件测试网6G{VZM(Pq
                        {
h3} k2O8zf B0                                return amount;
9AC9`#{^1v H?t}0                        }51Testing软件测试网rm t:V!EtGJ
                }51Testing软件测试网j,g3gc~!N2z
51Testing软件测试网.T6\[A-W:u%C
                public void Add(int num)
Lh3D6M CW y0                {
A8w\&`;w0                }51Testing软件测试网1^qL;B;D

b+{+bt` k Ba'X"I5R0                public void Sell()51Testing软件测试网2Ka']"^;C*N
                {
5@)@ [YXW0                }
'^9P2G6d3P2sg*z:Y#ZU0}51Testing软件测试网&M[$pd}5k4r

&lq n}8kuq0注意这段代码只是为了完成类的结构,方法的实现暂时先空着。然后将这段代码编译成一个dll动态连接库文件:UnitTest.dll。51Testing软件测试网*Cw]yU*wH(E L{"[
我们运行NUnit的图形测试工具,打开我们编译好的dll文件,点"Run"按纽,就可以看到如下画面:
J#K0x a:L0
T-l:Mg"tH/Q5|051Testing软件测试网"@+K me:K
很醒目红色,表示测试并没有成功,不过这个是在我们的预料之中的。51Testing软件测试网ys Pv-bS?3~/@5Q*O
接下来,我们向刚才的Ticket类中完成我们的Add方法实现代码:51Testing软件测试网 V!~;gt:aT@
public void Add(int num)
xR3AQze0{
/s'^,Jf-@G0amount += num;51Testing软件测试网%W)wJ/g"s
}
uIb5p'S%N,Z0保存,重新编译。
"S;A X,}1j6A8P0切换到NUnit,再点Run,可以看到:51Testing软件测试网U*JA e|.u

0A0nY @UdY0
4D n!I$H+i&N`}0Add方法已经变成绿色了,再接着将Sell方法也完成:
+}I#cKT7c$v*a0public void Sell()
!g^ G8J"L_#|izq0{
$t~8_ ZH%G{0amount -= 1;51Testing软件测试网-GQ?`%`,Xh
}51Testing软件测试网'PHy9H PBm$X5x}
再来测试,结果就变成:51Testing软件测试网L)jGo~

_;I5d|)xK051Testing软件测试网'U!zT m mLiQ$N
啊,总算变成美丽的绿色了,大家现在体会到环保的重要性了吧。 :)51Testing软件测试网qI_kR)Z5U jx$T
那么可以交任务了吗?等等,别急,还有个异常没测试呢,如果我们的Amount小于0的话,就会产生异常,那么,异常怎么测试呢?请接着看。51Testing软件测试网+M:?F`&[vDi$]|JV
51Testing软件测试网-z,^5Uu/_HZ k
--------------------------------------------------------------------------------51Testing软件测试网0zL'Phr*K5m
51Testing软件测试网&_(up9f/{i"l
测试异常:
2hU l G8C2j0还是跟上面一样,先写出测试代码:51Testing软件测试网z"^8vNYqn
[Test]51Testing软件测试网y5ae C m"M.i? e
        [ExpectedException(typeof(Exception))]51Testing软件测试网 G4M\ mh
        public void ExcpetionTesting()51Testing软件测试网+SBK({5Y Kjp
        {51Testing软件测试网#U.M.y Cl;Ab
                Ticket ticket = new Ticket();
}$]y6w \0                ticket.Add(3);
-Y8LO9`J7i9g*R0                ticket.Sell();51Testing软件测试网h}I$i0a&u#Hy"\3S
                ticket.Sell();51Testing软件测试网"PS%o(U)Yu;]j
                ticket.Sell();51Testing软件测试网~ ^YO5s/@l4]S
                ticket.Sell();51Testing软件测试网e*p+SdpS#Slg
        }
n:z7w&t&?#{A:Q051Testing软件测试网1wWdqB d(~Xd-W
其中,[ExpectedException(typeof(Exception))]表示我们希望能捕获到发生的异常,如果没有捕获到异常,则表示测试失败。51Testing软件测试网*Z&ESf,GzD0b(TV@)w
后面的代码很好理解,我们加了三张票,却卖了四张出去,这可不是炒股,以后没办法平仓的。 :)
?F r e^ b(iMaz0编译运行,我们看到以下的测试画面:
X1t7q+E]z051Testing软件测试网,en n6` F$LCr/H
51Testing软件测试网&dD0oj0il o"a
在Ticket类中,我们修改一下Sell方法,让它变成:51Testing软件测试网*p4uo6^ m
public void Sell()51Testing软件测试网7G;kG4t*x.YD
{
&?|2s:c+o0if(amount - 1 < 0)51Testing软件测试网+[Qv }9OB:ezW
throw new Exception("Amount不能为0");
5y0t.vU'ri+Oc+Dx/F0amount -= 1;51Testing软件测试网cL7_dH/~-N.v U
}51Testing软件测试网?0H bM n7y
编译,再测试,结果如下:51Testing软件测试网3J0l+mT9X K]
51Testing软件测试网2Gns)`7v!Zy
51Testing软件测试网w'iK@ l1Im/Ut
好了,到了这里就算完成我们的单元测试之旅了,大家对如何在C#中进行单元测试一定已经有了一个基本的认识。另外,NUnit并不是只针对C#,事实上,你可以在任何.Net语言中使用NUnit来测试你的单元,方法都一样。
j5q\.a'n?0
5a%O \L3dC*Y}DII2A0--------------------------------------------------------------------------------
1H)QWt&DV1iaM bR(}J051Testing软件测试网Ne*E@+O
总结:51Testing软件测试网rWV3M:x?'q
单元测试看上去虽然有点麻烦,但是它为程序员提供了一个安全的观点,让程序员对自己的程序更加有信心,在减少开发后期进行频繁Debug所耗费时间的同时也为应用软件提供了第一道安全防护网,因此,单元测试是提高开发效率和软件品质的一个重要的手段。51Testing软件测试网:P0|_#tSi[h
利用UNint,我们可以在.Net编程过程中非常方便的进行单元测试,它图形化的界面和简单而强大的测试框架为我们提供了一个非常舒适而有趣的测试环境,能够让程序员觉得进行单元测试并不枯燥乏味,习惯后甚至还能成为一种乐趣。51Testing软件测试网&A,o b8[DvCC F}(P
看完本文,如果你是引言中那个可怜的程序员的话,你现在就一定能轻松的面对你的项目经理,交上一份令人放心的代码答卷。
51Testing软件测试网 [-K1Ez_

{U+VE[0
测试者家园 2006-06-14 16:22 发表评论
51Testing软件测试网blkm#W(Z z

|bjxL,j^S0Link URL: http://www.cnblogs.com/tester2test/archive/2006/06/14/425859.html

TAG:

 

评分:0

我来说两句

Open Toolbar