扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:51CTO.com 来源:51CTO.com 2007年9月1日
关键字:
创建单元测试
当提到测试,Visual Studio真正的魔力就是当你在编辑器里右击一个方法时,它可以奇妙的创建你得到的单元测试选项。这个特性非常好,可以很容易的快速添加单元测试。但是,我遇到了一个小的哲学问题,它让你创建可以直接进入类并且访问私有方法的单元测试。
针对允许测试工具直接调用私有的或受保护的方法的争论就是它减化了测试(只写很少的代码),并且帮助扩宽了代码覆盖。这些争论是很诱人的,但是我同意这个观点,就是认为单元测试应该仅仅通过公共接口出现。单元测试是代码的首次使用,你想朝着其他的怎么使用它的方向来调整测试。如果有一些私有方法,这些方法你在没有short circuiting和直接的调用它们的情况下不能充分的测试,我必须知道是否代码需要被注册。为了阻止偶然的创建一个直接调用私有方法的单元测试,找到创建单元测试对话框,在右上角点击过滤,然后清空显示非公共项目。
我决不是一个绝对论者。我确定有一些示例,在示例里面它将帮助调用私有方法。但是,仅因为工具允许你做一些事情并不意味着你将依赖它。单元测试是测试的第一阶段,它也是你开始white box测试的第一个位置。
使用NUnit
我有一些项目,在项目中我们已经在一个扩充NUint的测试系统做出了很大投资。(对.NET Framework 2.0起作用的新版本即将被发布)在一个示例中,我们想要代码在NUnit和Visual Studio测试系统之间是便携式的。当计划这个时,我偶然发现很酷的一些事情,那就是需要最少的代码改变,并且允许代码与NUnit和Visual Studio一起工作。
我有一些项目,在项目中我们已经在一个扩充NUint的测试系统做出了很大投资。(对.NET Framework 2.0起作用的新版本即将被发布)在一个示例中,我们想要代码在NUnit和Visual Studio测试系统之间是便携式的。当计划这个时,我偶然发现很酷的一些事情,那就是需要最少的代码改变,并且允许代码与NUnit和Visual Studio一起工作。
|
我所需要做的就是使用NUnit测试属性改变我的方法为TestMethod,然后我就有一个在两种方式下工作的测试代码。
TimeOutAttribute
包含决大部分属性的文档固然非常好。但是,最重要的属性之一,TimeOutAttribute并没有包含在API文档中。当TESTRUNCONFIG文件允许你指定单元测试的全部超时值时,TimeOutAttribute让你指定一个单独的测试可能花费的最大毫秒数。我发现TimeOutAttribute在这些联系数据库的测试方法上没有价值,所以我密切注视这些查询。请注意,时间值包含一些测试运行器的时间。另外,机器的速度和性能将影响时间。使用你的测试进行实验来看一下时间选择是怎么在你的系统上工作的。
TestContext类我们只是简要的涉及到,它也是被单元测试向导添加进来的TextContext属性。主要的论述是关于当你正在使用DataSourceAttribute时通过使用TestContext类获得数据行。TestContext类有很多内容提供。文档显示出TestContext类标记为抽象,但是事实上支持你的单元测试的源类型是UnitTestAdapterContext,它来自于Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter.dl,你可以在<Visual Studio .NET install dir>\Common7\IDE\PrivateAssemblies 中发现这个DLL文件。你可以使用.NET Reflector查看UnitTestAdapterContext以此明白它是如何工作的。
或许这个类支持的最重要的方法就是WriteLine,你可以使用它添加额外的输出到单独的测试结果中。所有的编写都将出现在报告的额外信息部分。为了发现什么测试正在运行或测试开始于什么目录,你可以单个使用TestContext属性域TestName和TestDir。最后,如果你想为所有或部分测试设置时间器,调用TestContext.BeginTimer和TestContext.EndTimer。在标准的控制台输出部分,时间数据将显示在测试运行结果中。
为你写代码
我曾经提到,我已经包含了一个连同它的单元测试一起的真正单元。Bugslayer.Utility.DLL是一个我已经在项目之间拖拽的有用代码集合。ArgParser类是一个命令行论据分析类,这个类是基于在旧的.NET Framework SDK WordCount例子中的类。SystemMenuForm类是一个Windows窗体,这个窗体允许你在系统菜单中附加项目和作为常规时间回应点击操作。
我之所以编写GlobalMessageBox是因为每次使用一个消息框时我非常厌烦看到代码分析错误,Specify MessageBoxOptions。规则规定当使用一个消息框时,你需要浏览类,然后明确是否RightToLeft属性被设置为Yes。如果是,你必须调用合适的MessageBox.Show负载在MessageBoxOptions标记里通过。GlobalMessageBox为了我而关心这个,抑制错误和允许我的代码在右到左的语言系统中正确的工作。
对于Bugslayer.Utility.DLL的完全单元测试位于Bugslayer.Utility\Tests\Bugslayer.Utility.Tests目录中。在各种各样的CS文件中包括39个测试,提供了超过92%的代码覆盖。由于这是一个Windows 窗体的单元,此单元提出了消息框和控件,你不能够无人参与的运行它,但是它能够在15秒之内运行。
名称和位置
MSTEST.EXE最不成对的部分就是它的输出命名规范。如果你使用/RUNCONFIG选项来操作一个TESTRUNCONFIG文件,输出文件将使用在那个文件中规定的命名规范。如果你不使用/RUNCONFIG,或者设置为默认,所有的输出被写到.\TestResults\<user>_<machine> <timestamp>。我建议使用能够快速识别的名称。
MSTEST.EXE提供了/RESULTSFILE选项,但是这将导致输出文件名称丢失时间戳。另外,如果指定到/RESULTSFILE的文件名称退出,MSTEST.EXE将会失败。我所希望的就是指定一个我所集中工作的细节的名称,但是不需要手动的添加时间戳。
你可能会想可能的解决方法就是使用VSMDI测试源数据文件,这个文件你过去在测试管理器窗口中看到。事实上,MSTEST.EXE没有/TESTMETADATA选项来加载和运行测试。问题是你仅仅能指定一个VSMDI文件。
一个可能的解决方案就是创建一个单独的VSMDI文件,这个文件在你的代码里面导入所有其它的VSMDI文件。那的确可以工作,但是它也呈现出另外一个维护任务来回忆每一次你添加新的测试到代码中。
值得注意的是当运行VSMDI文件时你不能够告诉IDE或是MSTEST.EXE将输出文件放在什么位置。输出文件指向了VSMDI文件贮存的目录。建议在一个目录中保存测试,这个目录在版本控制里源代码之下,以致如果你共享项目,所有的测试代码将会跟随它。
由于VSMDI文件作为每一次测试的一部分,并且没有一种方式来集中输出,输出将围绕着你的源代码被分散。这并不是一个很大的处理,但是它意味着你必须手动的整理源树。在处理一些测试运行结果之后,我想要一种简单的方法来处理这个。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者