Visual Studio 2010 单元测试之一---普通单元测试
本文以Visual Studio 2010为例,来介绍如何在Visual Studio里面进行单元测试.
首先来介绍普通单元测试,这是进行顺序测试、压力测试的基础。如果在Visual Studio 2010(2008)里面没有发现下图中的Test菜单,请用Visual Studio安装光盘进行安装,因为Visual Studio单元测试插件安装时可能不是默认选项。
测试之前,我们要准备一些测试代码。或者从下面的链接下载完整的项目工程。
http://download.csdn.net/source/3014236
新建一个名为AppSample的Lib。里面有一个MathUtility文件,包含加减乘除四个方法。代码如下:
namespace TJVictor.UT.AppSample
{
public class MathUtility
{
public MathUtility() { }
public static int Add(int a, int b)
{
return a + b;
}
public static int Minus(int a, int b)
{
return a - b;
}
public static int Divide(int a, int b)
{
return a / b;
}
public static int Multiply(int a, int b)
{
return a * b;
}
}
}
创建单元测试项目有两种方法:
1.直接创建单元测试项目:File->New->Project->Test Project. 如下图:
2. 直接在需要创建单元测试的函数上创建:右击函数名->Create Unit Tests。 如下图
这样就创建好了单元测试项目。Visual Studio 会自动生成一个单元测试工程。推荐使用第二种方法创建,因为第一种方法创建的只有单元测试工程,第二种方法会把单元测试函数也一起创建了出来。
本文以第二种创建的方式为例,继续下一步,讲解单元测试文件。
创建好的单元测试工程如下图:
其中MathUtilityTest.cs就是自动生成的单元测试文件,打开可以看到类似如下代码。
[TestMethod()]
public void AddTest()
{
int a = 0; // TODO: Initialize to an appropriate value
int b = 0; // TODO: Initialize to an appropriate value
int expected = 0; // TODO: Initialize to an appropriate value
int actual;
actual = MathUtility.Add(a, b);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
关于单元测试的各种断言,不在本文讨论范围之内。下表列出Visual Studio 2010支持的断言及相关解释。
测试函数AddTest()的属性[TestMethod()]表示这个方法是个可运行单元测试方法,区别类中的其他方法(如一些测试辅助方法)。
需要特别注意的是:Assert.Inconclusive("Verify the correctness of this test method.");语句是默认添加的,意思是这个方法是Visual Studio自动创建,运行前自删除或注释此句,否则运行结果无法通过。
按上面的步骤,把MathUtility里面的所有方法都建立相应的单元测试,然后按F6进行编译。编译后,就可以在单元测试窗口中看到我们刚刚建立的测试方法了。
Test->Windows->Test List Editor如下图:
修改DivideTest代码如下:
[TestMethod()]
public void DivideTest()
{
int a = 100; // TODO: Initialize to an appropriate value
int b = 2; // TODO: Initialize to an appropriate value
int expected = 50; // TODO: Initialize to an appropriate value
int actual;
actual = MathUtility.Divide(a, b);
Assert.AreEqual(expected, actual);
//Assert.Inconclusive("Verify the correctness of this test method.");
}
在Test List Editor选中DivideTest方法后,右击如下图
1.Run Checked Tests:直接运行此单元测试函数。
2.Debug Checked Tests:以Debug模式运行。在此模式下运行单元测试函数,可以在单元测试函数(DivideTest)或是被测函数(MathUtility.Divide)中加断点,则程序会自动停留在断点处。
3.Open Test:打开此测试函数的方法,相当于双击。
4.Disable:把此测试方法置为无效。
左击Run Checked Tests后,运行结果如下图,证明测试通过:
重新修改DivideTest()程序如下:
[TestMethod()]
public void DivideTest()
{
int a = 100; // TODO: Initialize to an appropriate value
int b = 2; // TODO: Initialize to an appropriate value
int expected = 60; // TODO: Initialize to an appropriate value
int actual;
actual = MathUtility.Divide(a, b);
Assert.AreEqual(expected, actual);
//Assert.Inconclusive("Verify the correctness of this test method.");
}
再次运行,结果如下:
测试失败,原因是:期待值为60,实际值为50,断言失败。
重新修改DivideTest()程序如下:
public void DivideTest()
{
int a = 100; // TODO: Initialize to an appropriate value
int b = 0; // TODO: Initialize to an appropriate value
int expected = 60; // TODO: Initialize to an appropriate value
int actual;
actual = MathUtility.Divide(a, b);
Assert.AreEqual(expected, actual);
//Assert.Inconclusive("Verify the correctness of this test method.");
}
这次以Debug模式运行,则程序会在return a / b;抛出异常,显示被除数不能为0.
至此,一个简单的单元测试已经从头到尾跑了一遍。细心的读者一定会发现在MathUtilityTest.cs测试文件里面还有四个被注释掉的方法,下表列出了这四个方法的解释和用法。
Visual Studio 之所谓把这四个函数注释掉,原因是这四个函数只是示意性函数(从名字中就可以看出)。关键是看这四个函数的方法属性[ClassInitialize()],[ClassCleanup()], [TestInitialize()], [TestCleanup()]只要把相关的属性加到相关的方法上,那么这个方法就具有的上面所描述的功能。
单元测试适用范围:
1.验证函数正确性。对于一个函数,只要我们把相关的测试数据都写全,然后run一下,就知道是否都能通过。以后修改此方法后,只要再次run一下,就知道此次修改是否影响到了以前的测试用例,大大节省时间和提高正确率。
2.Debug程序。我们一般写后台代码时,都要写一个console或是winform小程序要调试验证所写的类是否能run起来,那么单元测试中的Debug模式就可以胜任此工作。
下面介绍两个使用时的小技巧。
1.可以在Test Result窗口里面导出测试结果。导出的结果包括一份测试报告和测试程序。证明此程序已经通过了报告中的所有测试用例,相当于Release了一个版本。
2.设置测试数量。每运行一次测试过程,就会生成一次测试报告和程序。Visual Studio默认次数是25,即超过25后,就会提示超出测试数次。我们可以通过下面的设置来提高次数。
Tool->Options->Test Tools->Test Execution,把里面的25改成100即可。如下图
至此,普通单元测试已经完成。请继续关注顺序单元测试。
Visual Studio 单元测试之二---顺序单元测试
本文会自动略去上篇中提到过的相关概念、方法。本文的例子可以使用下面的链接下载:
http://download.csdn.net/source/3014236
上一篇我们做的测试都是一个一个进行的,当然我们也可以一次性选择多个测试方法进行,但是测试运行的顺序以Test List Editor窗口中的默认列表顺序为准。在实际场景中,我们需要进行有顺序的单元测试,例如电子档案存档过程:创建电子档案->初步审核->确认无误->进行归档。那么上面四步可能每一步都是一个独立的单元测试函数,如果让它们按一定顺序执行呢?这就是我们这篇文章要讨论的。
上一篇我们已经建立了AddTest(),DivideTest(),MinusTest(),MultiplyTest()四个方法,假设就是上面电子存档的四个步骤。
右击UTProject->Add->New Test->Ordered Test如下图:
Note:其中Basic Unit Test是只包括[TestMethod]的单元测试文件模板,Unit Test是包括上文中提到的[ClassInitialize()],[ClassCleanup()], [TestInitialize()], [TestCleanup()]及[TestMethod]单元测试文件模板。其他模板我会在后续篇章中逐一介绍。
选择OrderedTest后,我们会发现多了一个OrderedTest1.orderedtest文件(为方便,我使用了VS默认命名规则,实际应用中,大家应把文件名改成统一实名)。打开后,会出现顺序挑选窗口,如下图:
运行方式和运行普通单元测试方法一样,在Test List Editor窗口,如下图:
最后介绍一下如何应用Test List Editor进行单元测试用例的归类。
当测试用例多起来后,要找一个测试方法就变得十分困难,这时就需要归类了。
打开Test List Editor->右击Lists of Test->Add Test List:如下图
将测试文件依次拖拽进新建的分类中,这样方便在多个测试方法中进行归类,查找。而且选取这个分类时,分类中的所有测试方法也一起被选中,下图显示归类后的对比图。
Visual Studio 单元测试之三---压力测试
我们都知道大名鼎鼎的LoadRuner,但是很少有人知道Visual Studio自带的Test也可以做些简单的压力测试,下面我们就介绍一下如何利用Visual Studio进行压力测试。
本文会自动略去上篇中提到过的相关概念、方法。本文的例子可以使用下面的链接下载:
http://download.csdn.net/source/3014236
做压力测试时,Visual Studio会记录大量的数据并把数据保存在数据库中,所以在进行讲解压力测试之间,让我们先把数据库的准备工作做好。
在SQLServer里面执行C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ loadtestresultsrepository.sql脚本,创建测试数据库(VS2008相应目录下面也有此脚本)
配置压力测试数据库:Test->Manage Test Controllers,配置刚建的数据库。如下图:
在MathUtility.cs文件中新建一个函数:
public static void PowerTest()
{
Random r1 = new Random(DateTime.Now.GetHashCode());
Random r2 = new Random(DateTime.Now.AddDays(1).GetHashCode());
double d = r1.Next() * r2.Next();
Random r3 = new Random(Convert.ToInt32(d));
string str = r3.Next().ToString();
StringBuilder buffer = new StringBuilder();
foreach (char a in str.ToCharArray())
buffer.Append(string.Format("{0}-{1}", a, a + a));
}
并创建这个函数的单元测试函数。
新建压力测试:
1.Add->New Test:
2.欢迎界面
3.设置这个测试场景的名称及思考时间(Think Time)和迭代思考时间
4.设置压力用户模型。
5.设置压力测试的混合模型。可以根据自己的测试场景需要来选择合适的模型。
6.设置压力测试函数,这些函数都是单元测试函数,可以增加多个压力函数且后面的人数为这个压力函数需要压力人数。
7.设置网络。压力测试与网络好坏关系密切时,此项起作用。 <!--[if !vml]--><!--[endif]-->
8.性能计数器。可以增加Perfmon里面的相关计数器。关于如何增加自定义计数器,不是本文所讨论的内容。我会另发一篇博文进行讨论。
9.设置压力时间及其他选项。
10.设置完成后的loadtest文件。
点击上图中的运行就可以起动本次压力测试了。如果你是按我上面的步骤设置的话,会看到类似下面的压力测试图(由于机器性能不同,局部数据会不同):
1.运行了3分钟时的图形
2.运行完成时的图形
运行完成后的压力测试报告
至此,我们就完成了一个完整的压力测试。压力测试的情景比较复杂,选项也比较多,有兴趣的话,请大家一个一个的试试。我这里就不把所有的选项含义及所用场景一一描述了。
最后介绍一下Load Test Manage.如下图:
可见,我做了多个压力测试,每次的数据都保存在刚才设定的数据库中了,我们可以通过这个窗体来查看、调用以前的压力测试结果及数据。
至此,压力测试的基本用法已经讲完,下面介绍Generic测试,数据库测试,UI界面测试。
Visual Studio 单元测试之四---Generic测试
这里的Generic我觉得理解为外部测试更合适。因为在这种测试模式下Visual Studio只是启动一个外部的程序,然后通过返回值(0:Passed,其他值:failed)来判断运行结果。
到目前为止,我还没有想到它的具体用途,可能微软就是为了兼容其他测试工具吧。比如把NUint作为外部程序来调用,让它跑一些测试用例。
创建Generic测试:
Add->Generic Test如下图:在第一个输入框中写入要运行的外部程序路径.
其他选项,比如命令行参数等,可以根据具体情况增加。
这时在Test List Editor窗口就可以看到刚才新建的Generic测试。
大家可以自行运行查看结果。
此至Generic Test已经完成了。我想说的是,Generic Test其实并不难,难的是什么时候用。我设想了一种情况:在一个大项目中,以前一直是用其他测试工具进行测试(如NUnit),而且具有大量的测试用例,现在改用VS的test,不可能把以前的用例全部迁移过来,也就是说存在两个测试工具要一起用的情况。在这种情况下,Generic Test的优势就体现出来了。如上图,我们可以把Generic和其他测试一起运行或把它们组合成顺序测试等。
Visual Studio 单元测试之五---数据库测试
数据库的单元测试主要是测试数据库中的数据是否符合特定的条件,Visual Studio 2010支持下面几种数据的单元测试类型(Visual Studio 2008 不支持数据库测试):
本文的例子可以使用下面的链接下载:
http://download.csdn.net/source/3014236
下面就开始Step By Step的建一个数据库单元测试实例。
1.新创建一个数据库测试文件:
2.如果你是每一次创建数据库测试文件,那么系统会自动提示你连接一个数据库:
3.创建成功后,如下图。点击去创建脚本文件。
4.如下图所示。UserGroup是我数据库中的一张表且里面只有一条数据。把系统默认的Inconclusive去掉,加上Execution Time和Row Count两个测试条件。注意看Value里面的解释。测试执行时间不能超过30秒,测试返回结果集只能返回0行。因为我们的测试结果集有一行数据,所以要修改rowCountCondition1的条件。
5. 在rowCountCondition1的属性框里面把0修改成1.如下:
6.在Test List Editor里面刷新一下,就可以看到我们刚建的数据库测试了,执行。
7.执行结果如下:
至此,数据库的单元测试界面操作基本完成。下面我们看一下后台代码。
通过代码我们可以了解到测试实际分为三个步骤:预测试(PretestAction),测试(TestAction),测试完成(PosttestAction)三部分。自动产生的代码,把预测试和测试完成的部分都省略了(this.DatabaseTest1Data.PosttestAction = null;this.DatabaseTest1Data.PretestAction = null;) 实际操作中,我们可以根据自己的需要,进行修改。
Visual Studio 单元测试之六---UI界面测试
UI界面测试其实就是录制操作路径(Mapping),然后按照路径还原操作顺序的一个过程。这个方法对于Winform和Webform都同样适用。下面以winform为例,来介绍如何进行录制。
1.新建一个Coded UI Test
2.然后选择录制。
3.屏幕右下方会出现UIMap.
4.打开一个Winform,使用“查看UI控件属性”这个功能可以查看所选控件的属性。
5.点击红色的开始录制,然后对被测的Winform程序进行一些操作。操作后暂停录制,然后可以查看所录制的操作过程和操作数据。如下图所示:
6.点击产生代码,系统会自动产生如下所示的操作代码。
7.重新打开被测的Winform程序,然后在Test List Editor里面选择刚生成的CodedUITestMethod1方法,执行它。则被测Winform程序会自动执行刚才所录制的所有操作。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tjvictor/archive/2011/02/09/6175499.aspx