【2012.11.8】VS2010 单元测试详解

Visual Studio 2010 单元测试之一---普通单元测试

本文以Visual Studio 2010为例,来介绍如何在Visual Studio里面进行单元测试.

首先来介绍普通单元测试,这是进行顺序测试、压力测试的基础。如果在Visual Studio 2010(2008)里面没有发现下图中的Test菜单,请用Visual Studio安装光盘进行安装,因为Visual Studio单元测试插件安装时可能不是默认选项。

测试之前,我们要准备一些测试代码。或者从下面的链接下载完整的项目工程。

http://download.csdn.net/source/3014236

新建一个名为AppSampleLib。里面有一个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),而且具有大量的测试用例,现在改用VStest,不可能把以前的用例全部迁移过来,也就是说存在两个测试工具要一起用的情况。在这种情况下,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 TimeRow 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),然后按照路径还原操作顺序的一个过程。这个方法对于WinformWebform都同样适用。下面以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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值