在该对话框中,“项目类型”我选择的是“Visual Basic”,如果想使用C#或者J#,请自行选择“其他语言”下的“Visual
C#”或“Visual J#”,反正操作差不多,下边也都会介绍到,不过VC就免谈了;“模板”我选的是“控制台应用程序”,您也可以选其它“模板”,我看的例子创建的就是“类库”;名称请自行设定,VB、C#、J#项目我都建了,分别起名为NUnitVB、NUnitCS和NUnitJS,设置好后,点击“确定”按钮。此时项目虽已创建,但尚未保存,请点击“文件”->“全部保存”,打开“保存项目”对话框:
通过“浏览”按钮设置“位置”,我设置的是本机G:\MDZPCK\Microsoft\MySY。
下面点击菜单“项目”->“添加引用”,打开“添加引用”对话框:
在“.NET”选项卡中找到组件名称为nunit.framework的一项,点击“确定”按钮,此时在项目中就可以使用NUnit类库了。
三、编写用于测试的类
用于测试的类很简单,名为Book,只有id和name两个属性,这两个属性将分别用于两个用例当中。
下面开始编写,请点击菜单“项目”->“添加类”,打开“添加新项”对话框:
在该对话框中,“类”模板被默认选中,请将名称修改为Book.vb或Book.cs、Book.jsl,然后点击“添加”按钮。
类创建后,需要修改代码,VB代码如下:
Public Class Book
Dim pid As String = Nothing
Dim pname As String = Nothing
Property id() As String
Get
Return pid
End Get
Set(ByVal Value As String)
pid = Value
End Set
End Property
Property name() As String
Get
Return pname
End Get
Set(ByVal Value As String)
pname = Value
End Set
End Property
End Class
代码比较简单,没什么可说的吧?下边是C#代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace NUnitCS
{
public class Book
{
private string pid = null;
private string pname = null;
public string id
{
get
{
return pid;
}
set
{
pid = value;
}
}
public string name
{
get
{
return pname;
}
set
{
pname = value;
}
}
}
}
也没什么可说的吧?下边是J#代码:
package NUnitJS;
public class Book
{
private String pid = null;
private String pname = null;
/** @property */
public void set_id(String value)
{
pid = value;
}
/** @property */
public String get_id()
{
return pid;
}
/** @property */
public void set_name(String value)
{
pname = value;
}
/** @property */
public String get_name()
{
return pname;
}
}
可以看到,J#代码与VB和C#代码有些不同,因为J#的语法是从Java演变过来的,所以其属性在定义时被拆成了set_XXX和get_XXX这样的两个方法。但仅有set_XXX和get_XXX这样的两个方法还不够,还需要使用@property指令进行说明。虽然用不用@property指令在调用时也没什么区别,但你可以尝试将变量pid和pname更名为id和name,重新编译;而后再将@property指令去掉,再重新编译。真的不一样。
至此,用于测试的类编写完成了。
四、编写测试用例
这里只用了一个类进行测试,名为BookTest,以前这样的类可能需要继承NUnit.Framework.TestCase类,但现在只需要对该类使用TestFixture属性进行标识即可,而无须继承了。BookTest类包含两个用例,分别对应该类的testId和testName方法,即每个方法实现了一个测试用例。注意,在NUnit中,这些用来实现测试用例的方法有两种手段进行标识:一个是以testXXX的格式来命名,一个是使用Test属性进行标识。此外,BookTest还有Init和Dispose这两个方法,并分别使用SetUp和TearDown属性来进行标识,前者在每个测试方法开始之前执行,多用来做初始化;后者在每个测试方法完成之后执行,多用来清理资源。注意,这两个方法的名称并没有什么限制,但必须用SetUp和TearDown属性进行标识。另外,NUnit还提供了TestFixtureSetUp和TestFixtureTearDown属性,功能与SetUp和TearDown类似,但前者是在所有用例执行之前做初始化、之后做清理,而后者是在每个用例执行之前做初始化、之后做清理。下面开始编写BookTest。
点击菜单“项目”->“添加类”,打开“添加新项”对话框,将名称改为BookTest.vb或BookTest.cs、BookTest.jsl,然后点击“添加”按钮创建该类。修改代码,VB代码如下:
Imports NUnit.Framework
<TestFixture()> _
Public Class BookTest
Dim bo As Book = Nothing
<SetUp()> _
Public Sub Init()
Console.WriteLine("测试开始!")
bo = New Book
Console.WriteLine("book对象被初始化!")
End Sub
<Test()> _
Public Sub testId()
bo.id = "001" '设置id属性的值为
'使用Assert查看id属性的值是否为
Assert.AreEqual("001", bo.id)
Console.WriteLine("id属性被测试!")
End Sub
<Test()> _
Public Sub testName()
bo.name = "ASP" '设置name属性的值为ASP
'使用Assert查看name属性的值是否为JSP,这是个必然出现错误的测试
Assert.AreEqual("JSP", bo.name)
Console.WriteLine("name属性被测试!")
End Sub
<TearDown()> _
Public Sub Dispose()
Console.WriteLine("book对象将被清理!")
bo = Nothing
Console.WriteLine("测试结束!")
End Sub
End Class
这里Init和Dispose方法没什么好说的,就是执行了对book对象的初始化和清理,不过testId和testName需要说明一下。前者是在对bo的id属性进行测试,首先赋值为”001”,然后使用Assert的AreEqual方法查看id属性中存放的值是否是期待的值,由于我的期待值也是”001”,所以执行后这个用例应该是成功的;后者则是对bo的name属性进行测试,也是首先赋值为”ASP”,然后使用Assert的AreEqual方法查看其值是否是期待的,由于我特意将期待值设定为根本不可能的”JSP”,因此这个用例执行后会出现一个错误。但请注意,由于我是特意要让测试出现错误,所以将期待值设定成了不可能的值,如果你是测试人员,请千万不要这么做,否则如果别的地方导致了错误,很容易给自己造成不必要的麻烦。
下面简单介绍一下上边用到的静态类NUnit.Framework.Assert。该类主要包含20个方法:
1.AreEqual()和AreNotEqual()方法,用来查看两个对象的值是否相等或不等,与对象比较中使用的Equals()方法类似。
2.AreSame()和AreNotSame()方法,用来比较两个对象的引用是否相等或不等,类似于通过“Is”或“==”比较两个对象。
3.Contains()方法,用来查看对象是否在集合中,集合类型应与System.Collections.IList兼容。示例:
Dim o As New Object
Dim al As New ArrayList
al.Add(o)
Assert.Contains(o, al)
4.Greater()和Less()方法,用来比较两个数值的大小,前者相当于大于号(>),后者相当于小于号(<)。
5.IsInstanceOfType()和IsNotInstanceOfType()方法,用来判断对象是否兼容于指定类型。示例:
Dim t As Type = New Object().GetType
Dim s As String = ""
Assert.IsInstanceOfType(t, s)
由于Object是.net中所有类型的基类,String类型兼容于Object,因此这个示例是能够运行通过的。而下边这个示例运行将是失败的:
Dim t As Type = New ArrayList().GetType
Dim s As String = ""
Assert.IsInstanceOfType(t, s)
6.IsAssignableFrom()和IsNotAssignableFrom()方法,用来判断对象是否是指定类型的实例。示例:
Dim t As Type = New Object().GetType
Dim s As String = ""
Assert.IsAssignableFrom(t, s)
这个示例与之前的示例是一样的,但由于字符串s不是Object类型的,因此无法运行通过。而下边这个实例可以运行通过:
Dim t As Type = New String("").GetType
Dim s As String = ""
Assert.IsAssignableFrom(t, s)
7.IsFalse()和IsTrue()方法,用来查看变量是是否为false或true,如果IsFalse()查看的变量的值是false则测试成功,如果是true则失败,IsTrue()与之相反。
8.IsNull()和IsNotNull()方法,用来查看对象是否为空和不为空。
9.IsEmpty()和IsNotEmpty()方法,用来判断字符串或集合是否为空串或没有元素,其中集合类型应与ICollection兼容。
10.IsNaN()方法,用来判断指定的值是否不是数字。
11.Fail()方法,意为失败,用来抛出错误。我个人认为有两个用途:首先是在测试驱动开发中,由于测试用例都是在被测试的类之前编写,而写成时又不清楚其正确与否,此时就可以使用Fail方法抛出错误进行模拟;其次是抛出意外的错误,比如要测试的内容是从数据库中读取的数据是否正确,而导致错误的原因却是数据库连接失败。
12.Ignore()方法,意为忽略,用来忽略后续代码的执行,用途可以参考Fail()方法。
此外,NUnit还提供了一个专用于字符串的静态类NUnit.Framework. StringAssert,该类主要包含4个方法: