1,TestFixture
<TestFixture()> _
Public Class Class1Test
Public Sub New()
End Sub
end class
这个类包含了测试代码,你需要给我看一下。然后NUnit就到这个类里面去看看是否有需要他出马的机会。
2,Test
Public Sub FindMaxTest()
'定义一个数组
Dim list1 As Int32() = {1, 3, 10, 4}
Dim my As New Class1
'测试数组list1中的最大整数是不是10。
Assert.AreEqual(4, my.FindMax(list1))
End Sub
这里的<Test()>(C#中为[Test]),这个特性告诉NUnit:
这是一个需要测试的方法,你给我测试一下,并用颜色告诉我结果(红色说明测试失败,绿色说明测试成功)。
对应到NUnit的gui中如下图:
图中左边那个灰色的圆点(FindMaxTest)就是由Test特性标示出来的一个需要测试的方法,然后我们可以通过按“Run”来运行这个测试,NUnit将通过颜色来返回。
这是NUnit最主要的2个Attribute,有了这2个,就可以编写单元测试了。
除了这2个Attribute之外,还有一些其他的Attribute,可以提供给我们更强大的功能,下面列出一些常用的:
标识测试类 |
TestFixture |
标识测试方法 |
Test |
标识测试类初始化函数 |
TestFixtureSetup |
标识测试类资源释放函数 |
TestFixtureTearDown |
标识测试用例初始化函数 |
Setup |
标识测试用例资源释放函数 |
TearDown |
标识忽略该测试方法 |
Ignore |
标识该用例所期望抛出的异常 |
ExpectedException |
标识测试用例的分类 |
Category |
让我们接下去讲解其他Attribute:
3,TestFixtureSetup和TestFixtureTearDown
TestFixtureSetup这个特性的作用是为整个测试类初始化一些资源,准备好测试环境,然后给该测试类的几个测试(Test)使用,而TestFixtureTearDown则是把TestFixtureSetup初始化的一些资源释放掉。
我们可以通过下面这个例子来更好的理解:
<TestFixture()> _
Public Class Class1Test
Private con As Connection
<TestFixtureSetUp()> _
Public Sub MyFixtureSetUp()
'打开数据库联接
conn = New Connection("sqlXXX", user, password)
conn.open()
End Sub
<TestFixtureTearDown()> _
Public Sub MyFixtureTearDown()
'关闭数据库联接
conn.close()
End Sub
<Test()> _
Public Sub Mytest1()
'使用conn作某些测试
End Sub
<Test()> _
Public Sub Mytest2()
'使用conn作某些测试
End Sub
End Class
当你用NUnit测试Mytest1,Mytest2这2个test时,程序的运行顺序是这样的:
MyFixtureSetUp(初始化测试环境)
Mytest1(test1)
Mytest2(test2)
TestFixtureTearDown(释放资源)
4,Setup和TearDown
这2个特性和TestFixtureSetup,TestFixtureTearDown有点类似,区别在于:
Setup将在每个test之前运行,TearDown将在每个test之后运行。简单的说TestFixtureSetup,TestFixtureTearDown在一个测试类中之会运行一次;而Setup和TearDown,这个测试类有几个test被测试,就将运行几次。
举例说明:
<TestFixture()> _
Public Class Class1Test
Private con As Connection
<SetUp()> _
Public Sub MyFixtureSetUp()
'打开数据库联接
conn = New Connection("sqlXXX", user, password)
conn.open()
End Sub
<TearDown()> _
Public Sub MyFixtureTearDown()
'关闭数据库联接
conn.close()
End Sub
<Test()> _
Public Sub Mytest1()
'使用conn作某些测试
End Sub
<Test()> _
Public Sub Mytest2()
'使用conn作某些测试
End Sub
End Class
当你用NUnit测试Mytest1,Mytest2这2个test时,程序的运行顺序是这样的:
SetUp(初始化测试环境)
Mytest1(test1)
TearDown(释放资源)
SetUp(初始化测试环境)
Mytest2(test2)
TearDown(释放资源)
可以看出,每个test前后都运行了SetUp和TearDown
对3和4这2组特性的选择,我个人在实际使用中感觉差别不大,随便用哪种都行,2种都用也无不可。我一般是用TestFixtureSetup和TestFixtureTearDown,一次性把资源都设置好,然后再一次性释放,写起来方便
5,Ignore
临时忽略一些test。
在以下情况可能会用到:
(1),你的测试用例写好了,但实际代码却还没完成,这样的话测试肯定是不能通过的,但是你又不想看到NUnit抛出一个红灯笼,你就可以暂时用Ignore忽略掉这个test。NUnit会抛出一个黄灯,提醒你这个测试被忽略了。(不过,抛出个红灯笼也有好处的,它能鞭策你快点写好代码,哈哈)
(2),有些测试可能耗费非常长的时间(比如几个小时),你展示不想测试它们,而想等半夜再测试,你就可以暂时Ignore它们。(不过,推荐用Category特性来把这些长时间测试分类出来,而不是用Ignore,这个将在后面讲到)
实例说明:
Public Sub FindMaxTest()
'定义一个数组
Dim list1 As Int32() = {1, 3, 10, 4}
Dim my As New Class1
'测试数组list1中的最大整数是不是10。
Assert.AreEqual(10, my.FindMax(list1))
End Sub
(C#中为[Test,Ignore("XXX")] )
运行NUnit,我们将看到如下结果:
6,ExpectedException
标识该用例所期望抛出的异常
有时候我们知道在特定条件下我们的程序将会抛出某个异常,我们就可以用ExpectedException这个特性在测试代码中验证,程序是否如我们所想的抛出了这个异常。
如,我们那个求最大值的方法,如果传进去一个空的int32数组,应该会抛出一个NullReferenceException异常,为了验证我的猜想,我写了如下测试:
Public Sub FindMaxTest()Sub FindMaxTest()
'定义一个数组
Dim list1() As Int32 = {1, 3, 10, 4}
Dim list2() As Int32 = {1, 3, 4, 10}
Dim list3() As Int32 = {10, 3, 1, 4}
Dim list4() As Int32 = {-2, -1, -3}
Dim my As New Class1
'测试数组list1中的最大整数是不是10。
Assert.AreEqual(10, my.FindMax(list1))
'测试边界值
Assert.AreEqual(10, my.FindMax(list2))
Assert.AreEqual(10, my.FindMax(list3))
'测试负数数组,数组中最大值应该是-1
Assert.AreEqual(-1, my.FindMax(list4))
End Sub
<Test(), ExpectedException(GetType(NullReferenceException))> _
Public Sub TestForException()
Dim list1() As Int32
Dim my As New Class1
my.FindMax(list1)
End Sub
(C#中为[Test,ExpectedException(Typeof(NullReferenceExcepton))] )
运行NUnit,如下:
果然如此,程序的确抛出了NullReferenceException。而假如系统没有如我们所料抛出异常,或者抛出的不是此类异常,NUnit则会给我们个红灯笼。
7,Category
分类。
该特性可以把一些测试分成不同的种类,比如我们前面提到的,假如有些测试很耗时,我们就可以把它们分类成LongTime测试,而把其他的测试分类成ShortTime测试,然后,我们可以在NUnit中选择只运行ShortTime的测试,那些LongTime的测试则可以在夜晚自动构建的时候运行它们。
使用举例如下:
<TestFixture()> _
Public Class Class1Test
<Test(), Category("ShortTime")> _
Public Sub Mytest1()
End Sub
<Test(), Category("ShortTime")> _
Public Sub Mytest2()
End Sub
<Test(), Category("LongTime")> _
Public Sub Mytest3()
End Sub
<Test(), Category("LongTime")> _
Public Sub Mytest4()
End Sub
End Class
(C#中为[Test][Category(“ShortTime”)] )
这个测试类中有2种测试方法:ShortTime和LongTime,
运行NUnit,选择"Categories",我们将看到,Available Categories中看到有2种分类,选择“shortTime”,然后运行,只有ShortTime的那些测试方法被运行了。
除了这些Attribute之外,其实还有一些,不过我在实际使用中很少用到,我就不拿出来讲了。
下篇学习笔记,我将列举几种单元测试与项目结合的方法。