Tony Gong的技术Blog  
技术旅途中蹒跚的行者
最近一段时间在研究单元测试,先记录一下学习记录吧。

首先,单元测试的目的,我觉得最主要有以下几点:
1,可以保证code实现的功能和我们期望的一致。
2,当我们增加了新的功能时,常常会破坏原有的代码而不自知,n久之后,突然发现某诡异bug,需要花费很久才能查出来。而有了单元测试,每当你添加新功能,以及新功能的单元测试代码之后,运行一下这个工程的单元测试,马上就能看到你的新功能是否破坏了你的原有功能。
当然,前提是单元测试写的够完整。
3,通过单元测试,可以找到很多不易发现的bug,比如边界条件错误等。这会使得我们的程序更加健壮。
4,对原有代码编写单元测试,常常会发现原有代码由于耦合度过高,不容易测试,这时候,通过令代码更加容易测试而去改善代码得设计。测试驱动重构?汗。。。。。


先举个简单的例子来说明下单元测试的功能,具体使用NUnit的方法,后面再说吧,现在就只用例子来说明下NUnit的功能。
环境为.net1.1 vb.net +NUnit2.27
我编了一个对传入整数数组,查找出最大值的方法,代码如下:
 1
 2Public Class Class1
 3    ''' -----------------------------------------------------------------------------
 4    ''' <summary>
 5    ''' 查找最大值
 6    ''' </summary>
 7    ''' <param name="list">传入整数数组</param>
 8    ''' <returns>返回数组中的最大值</returns>
 9    ''' <remarks>
10    ''' </remarks>
11    ''' <history>
12    '''     [Tony]    2006-4-20    Created
13    ''' </history>
14    ''' -----------------------------------------------------------------------------
15    Public Function FindMax(ByVal list As Int32()) As Int32
16        Dim i As Int32
17        Dim max As Int32
18
19        For i = 0 To list.Length - 1
20            If list(i) > max Then
21                max = list(i)
22            End If
23        Next
24
25        Return max
26    End Function

27
28End Class

然后编写测试类:
 1Imports NUnit.Framework
 2
 3<TestFixture()> _
 4Public Class Class1Test
 5
 6    ''' -----------------------------------------------------------------------------
 7    ''' <summary>
 8    ''' 测试Class1类的FindMax方法
 9    ''' </summary>
10    ''' <remarks>
11    ''' </remarks>
12    ''' <history>
13    '''     [Tony]    2006-4-20    Created
14    ''' </history>
15    ''' -----------------------------------------------------------------------------
16    <Test()> _
17    Public Sub FindMaxTest()
18        '定义一个数组
19        Dim list1 As Int32() = {13104}
20
21        Dim my As New Class1
22        '测试数组list1中的最大整数是不是10。
23        Assert.AreEqual(10, my.FindMax(list1))
24    End Sub

25End Class

运行NUnit,


按Run运行NUnit:


测试通过了,但我的测试类里面仅仅判断了正数的数组,我们还必须做更完整的单元测试,比如测试负数,边界测试等。
下面是更新过的测试类:
 1Imports NUnit.Framework
 2
 3<TestFixture()> _
 4Public Class Class1Test
 5
 6    ''' -----------------------------------------------------------------------------
 7    ''' <summary>
 8    ''' 测试Class1类的FindMax方法
 9    ''' </summary>
10    ''' <remarks>
11    ''' </remarks>
12    ''' <history>
13    '''     [Tony]    2006-4-20    Created
14    ''' </history>
15    ''' -----------------------------------------------------------------------------
16    <Test()> _
17    Public Sub FindMaxTest()
18        '定义一个数组
19        Dim list1() As Int32 = {13104}
20        Dim list2() As Int32 = {13410}
21        Dim list3() As Int32 = {10314}
22        Dim list4() As Int32 = {-2-1-3}
23
24        Dim my As New Class1
25        '测试数组list1中的最大整数是不是10。
26        Assert.AreEqual(10, my.FindMax(list1))
27
28        '测试边界值
29        Assert.AreEqual(10, my.FindMax(list2))
30        Assert.AreEqual(10, my.FindMax(list3))
31
32        '测试负数数组,数组中最大值应该是-1
33        Assert.AreEqual(-1, my.FindMax(list4))
34
35    End Sub

36End Class

重新运行NUnit,如下:


哦?31行出错:
Assert.AreEqual(-1, my.FindMax(list4))
期望值是-1,但实际却是0,我们回头看一下代码,很容易发现,原来是
Dim max As Int32
这里出错了,max的初始值就是0,所以后面循环判断最大值,对于负数来说,是错误的,重新修改代码:
 1Public Class Class1
 2    ''' -----------------------------------------------------------------------------
 3    ''' <summary>
 4    ''' 查找最大值
 5    ''' </summary>
 6    ''' <param name="list">传入整数数组</param>
 7    ''' <returns>返回数组中的最大值</returns>
 8    ''' <remarks>
 9    ''' </remarks>
10    ''' <history>
11    '''     [Tony]    2006-4-20    Created
12    ''' </history>
13    ''' -----------------------------------------------------------------------------
14    Public Function FindMax(ByVal list As Int32()) As Int32
15        Dim i As Int32
16        Dim max As Int32 = Int32.MinValue
17
18        For i = 0 To list.Length - 1
19            If list(i) > max Then
20                max = list(i)
21            End If
22        Next
23
24        Return max
25    End Function

26
27End Class


再运行NUnit,这次终于正确了。

冲这个例子可以看出,单元测试能帮我们发现一些比较难以发现的bug。

下一篇,我再具体写一些NUnit的使用方法。
posted on 2006-04-20 21:30  Tony.Gong  阅读(2723)  评论(7编辑  收藏  举报