【转】VS2005如何进行单元测试

上一篇 / 下一篇  2011-09-09 10:45:34 / 个人分类:测试相关

 

  首先我们要解决一个问题,为什么我们需要做单元测试?这个问题,对有经验的老程序员来说,并不算是问题。一个软件在开发的过程中,倘若不是非常微型的软件,那么我们通常会划分出若干个功能模块来,然后一个模块一个模块的进行开发。每个子模块完成后,我们并不知道它是否能正常的运行,尤其是当这个模块只是个中间件类似的代码块,那么我们为了减少之后可能出现的问题和debug的难度(可以想象,如果在整合时期进行测试或者是甚至还有其他的模块需要依赖该模块才能进行开发的时候,尽早的测试将会是非常的重要),我们常常会对这单个模块进行测试,比如写段小程序,人为的写入几个参数来调用组件等。不用怀疑了,这就是单元测试。我相信,大部分的程序员都做过这样的工作,而且也许还有许多程序员就如我上面所说的,单独写段小程序来进行单元测试(我自己以前也是如此),现在我们需要认真考虑下下一个问题了:如何进行高效的,高可靠的,甚至自动化的单元测试?

  VSTS里的UnitTest可以帮助我们实现我们希望的绝大多数功能。我们从实际的项目开发入手来介绍。假设我们新建了一个。net项目,嗯,这是一个有关缓存的子项目,名字叫MyCache。我们很认真的设计了项目的架钩,进行了可行性分析,接口和抽象的建立,具体对象的建立,关系建立,最后编码完成了。项目经理叫我们不要高兴的太早,他要求我们必须对这个项目进行可靠的单元测试,因为这个子项目非常重要,将会被许多项目引用。尽管我们很有信心,但是没有办法,我们依然需要进行单元测试。我们使用了VisualStudioTeamSystem开发了这个项目,于是我们理所当然的使用自带的UnitTest工具进行单元测试。

  Step1 我们需要建立项目文件与测试文件的映射关系。

  难道要我们去手动创建吗?这可是整个项目啊,里面也许包含了几十个类,数百个方法…当然没那么复杂!实际上,我们需要做的工作很少,只是动动鼠标,等几秒就可以了:)

  在VS2005的IDE环境下,选择menu里的Test,继续选NewTest项,这时将跳出个窗体,里面可以选择测试项目类型,这里我们选择UnitTestWizard,确定,输入测试项目名,然后将又出现一个窗体,里面包含你当前的solution里的所有project,我们选上我们的MyCache,确定。OK,看见一个进度条,这是在执行测试代码的映射工作,等结束后,你就会发现,已经建立了一个测试项目了,里面的文件完全对应你的目标项目,每个类包含的方法也是与目标类的方法一一对应,非常简单,cool,missioncomplete!

  Step2 运行我们的测试项目。

  接下来,我们怎么进行测试呢?里面有许多的类和方法,很多方法上还带有像TestMethod这样的标签属性,但是我们关心的是,如何进行测试?绝对不是通常的F5来运行:(,在VSTS里,单元测试实际上有专门的管理工具。再次选到menu上的Test选项,移到windows上展开自菜单,里面有好几个选项,我们选择TestManager打开。在IDE窗口内出现了一个视图结构的东西,在分割线的右边是一个listView,里面全是当前测试项目包含的方法,我们随便选几个方法给勾上,右键,RunCheckedTest,下边马上有出现了TestResult窗体,里面就是刚才你选择的方法。如果不出意外的话,你的这个窗体内的方法result应该都是failed之类的数据,嗯,先不管这个,最起码,我们已经运行了一次测试项目了,虽然有些奇怪,不过我们已经知道了如何运行一个测试项目了,那么再进入下一个step吧:)

  Step3 看看我们的测试代码里都有些什么。

  虽然知道了怎么运行测试项目,但莫名其妙的全部出错,是怎么回事呢?我们进入测试项目具体的代码来看看。

  我们会发现,每个测试类的名称就是对应的目标类的名称+“test”,里面的方法也是如此,如果是构造函数,则是诸如

  ConstructorTest或ConstructorTestN这样的形式,N为重载次数。每个方法里面的代码看上去也不奇怪,只是构造参数来调用而已,最后通过断言来判断(用过NUnit的朋友不会陌生吧?)。我们试着直接把一个方法里的断言去掉看看,编译,TestManager,run,嘿,果然,去掉断言的方法就pass了!看来蒙老大不难呢,只要把所有的方法的断言都给去掉,然后给老大看测试后的结果,呵呵…

  Step4 深入的了解一下方法上带有的属性的含义。

  每个方法上几乎都带有TestMethod这个属性,我们直觉告诉我们,这肯定是表示被测试函数的意思。事实也正是如此,在UnitTest里,有许多测试属性,常用的如下:

  属性                                        描述

  TestClass()                     该属性表示一个测试装置。

  TestMethod()                   该属性表示一个测试用例

  AssemblyInitialize()        在执行为执行选择的第一个TestClass()中的第一个TestMethod()之前,执行带有该属性的方法。

  ClassInitialize()              带有该属性的方法在执行第一个测试之前调用。

  TestInitialize()                 带有该属性的方法在执行每个TestMethod()之前调用。

  TestCleanup()                带有该属性的方法在执行每个TestMethod()之后调用。

  ClassCleanup()             带有该属性的方法在执行ALL测试之后调用。

  AssemblyCleanup()       在执行为执行选择的第一个TestClass()中的第一个TestMethod()之后,执行带有该属性的方法。

  Description()                  提供关于给定TestMethod()的描述。

  Ignore()                           由于某种原因忽略TestMethod()或TestClass()。

  ExpectedException()     当测试特定异常时,如果使用该属性指定的异常不是从实现代码引发,则测试不会失败。

  需要注意的是,上面的属性不是可以适用于所有方法的,比如AssemblyInitialize()和ClassInitialize()是必须是静态方法的属性。

  我们可以把初始化的操作放在他们里进行。


TAG:

 

评分:0

我来说两句

Open Toolbar