创建测试项目
创建测试项目
执行单元测试的第一个步骤是创建测试项目。测试项目类类似于包括Visual Basic或另一.NET语言代码的标准项目,它也出现在【解决方案资源管理器】窗口中,并包括一个或多个源文件,这些源文件中又包含一个或多个类。这些类之所以特殊是因为它们都拥有一个自定义属性。
可以采用多种方式创建测试项目:例如,可以从【添加新项目】对话框中选择【测试项目】模板,从【文件】菜单的【添加】子菜单中可以打开此对话框。也可以使 用【测试】菜单上的【新建测试】命令,此命令将打开一个对话框,以创建几种类型的测试模块。无论采用哪种方式,在创建测试项目时,所使用的名称应当类似于 包含被测试代码的项目名称(例如,MathWorkbenchTest),以便清楚地表明【解决方案资源管理器】中的项目为测试项目。
如图为【添加新测试】对话框。
所有的新测试项目都包含AuthoringTests.txt文件(带有指令的文本文件)和UnitTest1.vb文件(一个空测试类,可以在其中放置测试方法),可以在【添加新测试】对话框中改变后一个文件的名称。
还会注意到,Visual Studio已经在【解决方案资源管理器】中添加了一个名为Solution Items的新文件夹,它又包含两项:solutionname.vsmdi和localtestrun.testrunconfig。测试过程的细节存储在后一文件中。
用鼠标右击Class Triangle语句,并从上下文菜单中选择【创建单元测试】命令。这一操作打开【创建单元测试】对话框。在此对话框的上部选择希望测试哪些类和方法,在 其下边缘附近出现【输出项目】组合框,用以指定将向哪个测试项目添加测试代码。(组合框中的其他选项允许创建一个新项目。)【设置】按钮显示一个对话框, 可以从中控制将要生成代码的一些特性。对于这个例子,只需要接受所有默认设置即可。
如图为【创建单元测试】对话框。
确认选择了Triangle类及其三个成员,然后单击【确定】。Visual Studio将向测试项目中添加一个名为TriangleTest.vb的新文件。如果此文件已经存在,Visual Studio将所生成的代码与现有内容合并。
'以下代码由 Microsoft Visual Studio 2005 生成。
'测试所有者应该检查每个测试的有效性。
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System
Imports System.Text
Imports System.Collections.Generic
Imports WindowsApplication5
'''<summary>
'''这是 WindowsApplication5.Triangle 的测试类,旨在
'''包含所有 WindowsApplication5.Triangle 单元测试
'''</summary>
<TestClass()> _
Public Class TriangleTest
Private testContextInstance As TestContext
'''<summary>
'''获取或设置测试上下文,上下文提供
'''有关当前测试运行及其功能的信息。
'''</summary>
Public
Property TestContext() As TestContext
Get
Return testContextInstance
End Get
Set(ByVal value As TestContext)
testContextInstance = Value
End Set
End
Property
#Region "附加测试属性"
'
'编写测试时,可使用以下附加属性:
'
'使用
ClassInitialize 在运行类中的第一个测试前先运行代码
'
'<ClassInitialize()>
_
'Public
Shared Sub MyClassInitialize(ByVal testContext As
TestContext)
'End
Sub
'
'使用
ClassCleanup 在运行完类中的所有测试后再运行代码
'
'<ClassCleanup()>
_
'Public
Shared Sub MyClassCleanup()
'End
Sub
'
'使用
TestInitialize 在运行每个测试前先运行代码
'
'<TestInitialize()>
_
'Public Sub
MyTestInitialize()
'End
Sub
'
'使用
TestCleanup 在运行完每个测试后运行代码
'
'<TestCleanup()>
_
'Public Sub
MyTestCleanup()
'End
Sub
'
#End Region
'''<summary>
'''GetArea()
的测试
'''</summary>
<TestMethod()> _
Public Sub
GetAreaTest()
Dim sideA As Double 'TODO: 初始化为适当的值
Dim sideB As Double 'TODO: 初始化为适当的值
Dim sideC As Double 'TODO: 初始化为适当的值
Dim target As Triangle = New Triangle(sideA, sideB, sideC)
Dim expected As Double
Dim actual As Double
actual = target.GetArea
Assert.AreEqual(expected, actual,
"WindowsApplication5.Triangle.GetArea 未返回所需的值。")
Assert.Inconclusive("验证此测试方法的正确性。")
End
Sub
'''<summary>
'''GetPerimeter() 的测试
'''</summary>
<TestMethod()> _
Public Sub
GetPerimeterTest()
Dim sideA As Double 'TODO: 初始化为适当的值
Dim sideB As Double 'TODO: 初始化为适当的值
Dim sideC As Double 'TODO: 初始化为适当的值
Dim target As Triangle = New Triangle(sideA, sideB, sideC)
Dim expected As Double
Dim actual As Double
actual = target.GetPerimeter
Assert.AreEqual(expected, actual,
"WindowsApplication5.Triangle.GetPerimeter 未返回所需的值。")
Assert.Inconclusive("验证此测试方法的正确性。")
End
Sub
'''<summary>
'''New(ByVal
Double, ByVal Double, ByVal Double) 的测试
'''</summary>
<TestMethod()> _
Public Sub
ConstructorTest()
Dim sideA As Double 'TODO: 初始化为适当的值
Dim sideB As Double 'TODO: 初始化为适当的值
Dim sideC As Double 'TODO: 初始化为适当的值
Dim target As Triangle = New Triangle(sideA, sideB, sideC)
'TODO: 实现用来验证目标的代码
Assert.Inconclusive("TODO: 实现用来验证目标的代码")
End
Sub
End Class
有几点很有意义的细节需要注意。
1、此测试项目引用两个其他程序集:必须被测试的可执行文件和Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll库,后者包含几个可能从内部测试方法中使用的类型。
2、TriangleTest类标记有TestClass属性,这一属性使Visual Studio中的单元测试子系统可以看到这个类。
3、各个测试方法标记有TestMethod属性。在运行该测试时,Visual Studio将支持所有标有这一属性(并包含在标有TestClass属性的类中)的方法。
4、Initialize和Cleanup方法标有TestInitialize和TestCleanup属性,Visual Studio将分别在每个标有TestMethod的方法之前和之后调用这两个方法。因此,可以将这些方法用于该测试类中的所有测试共用的代码。
5、Visual Studio已经在各个测试方法中创建了大量语句,例如,实例化用于测试的Triangle对象,还有一些TODO注释(指向希望进行手动修改的代码 段)。在所有这些测试方法结束时,都调用Assert.Inconclusive方法,这是一种提示:在修改该方法中的源代码之前,单元测试机制不会从该 方法的输出之中了解到任何信息。
Assert对象公开很多可以在测试方法中使用的方法。AreEqual和AreNotEqual方法检查两个值是否相等;IsTrue和IsFalse 方法检查布尔条件的结果;AreSame和AreNotSame方法检查两个对象引用是否指向相同对象(类似与Visual Basic的Is运算符);IsNull和IsNotNull方法检查一个对象引用是否为Nothing;IsInstanceOfType和 IsNotInstanceOfType方法检查被测试过程返回的值是否为给定类型。
'A few example of the methods exposed by the
Assert type
Assert.IsNull(actual, "The method didn't return Nothing")
Assert.IsTrue(actual >= 0, "The method returning a
negative value.")
Assert.IsInstanceOfType(actual, GetType(String), "The method didn't
return a string")
Fail方法无条件地使测试失败,这一方法对于检查复合条件非常有用。
If actual < -10 OrElse actual
> 10 Then
Assert.Fail("The method returned a value outside the range
[-10,10]")
End If