游泳

强化Visual Studio单元测试(1)

2019-12-03 01:35:47来源:励志吧0次阅读

Visual Studio 2005给用户带来了很多针对表的新特性,以致它似乎具有压倒性的优势。最令人兴奋的其中一个就是新的单元测试特性,它位于在主菜单栏中的测试菜单里面。当我们暂时使用在基于.Net Framework开发里面的一些优秀的单元测试工具时,这些新的单元测试特性提供了清晰的集成和以前缺少的一个侧重。

然而,这个单元测试工具的确也有一些缺点。在这里,我将论述我在使用这个新的单元测试工具时遇到的缺陷和问题。我已经做出了一个真实的模块,我一直使用它的单元测试进行工作,所以你手头上将有一个有用的例子。注意所有的这些问题都是固定的,你可以很自然的在你的开发工作室中立即实现这些测试工具。

然而,这个单元测试工具的确也有一些缺点。在这里,我将论述我在使用这个新的单元测试工具时遇到的缺陷和问题。我已经做出了一个真实的模块,我一直使用它的单元测试进行工作,所以你手头上将有一个有用的例子。注意所有的这些问题都是固定的,你可以很自然的在你的开发工作室中立即实现这些测试工具。

针对这个专栏,我假设你已经阅读了文档中的”Writing Quality Code”和”Working with Unit Tests”部分。这些页面提供了一个很好的预览,我将在这里列举一些实用性方面。如果你已经有了针对开发人员的Visual Studio® Team System或者Team Edition,你也将有针对测试人员的这些工具。Team Edition for Tester文档包括了这些工具,还有所有重要的类库文档,这些文档用于扩展或者与测试环境相互作用。

密切注意Hardcoded路径

使用单元测试向导在一个新的项目上添加测试是一件非常容易的事情。这个便利的特点可以节省你数百个小时的打字时间(微软的开发者为此应收取很多费用)。但是,一些事情在幕后发生了,并且导致你很悲伤:路径是hardcoded!这是一个问题,例如,当你移动一个测试到另一台机器或是目录时就会发生。我希望一个Visual Studio 2005的Service Pack允许你为测试设置一个开始路径,hardcoded路径将使用相对路径。目前,但是解决hardcoded路径的容易方式就是在团队中有一个慈善的独裁者,它总是判断和颁布所有的驱动和路径。如果它是一个小的项目,这种解决方案是很好的。另一个,一些实用的工作区在你的路径中将引用%testdeploymentdir%环境变量。当测试运行时它被设置。

Hardcoded路径出现的第一个地方就是在VSMDI文件中,这个文件是一个大的包装皮里面包含简单的测试列表。当你打开一个VSMDI文件,然后它不能找到测试集或者TESTRUNCONFIG文件,你将被提示为这些项目指出位置。我发现有意思的事情是下一次我再打开相同的VSMDI文件时,它会发现所有的东西。很明显,更新的路径一定存储再某个地方,但是VSMDI文件本身并没有被改变。我再VSMDI文件驻留的目录中发现一个隐藏文件,名称为name<filename>.VSMDI.OPTIONS。

当我打开VSMDI.OPTIONS文件时(它是一个常见的XML文件),我摇晃我的头,感觉受挫一样。就像你在Figure 1中看到的一样,在VSMDI文件中很明显的有路径搜索的支持,但是在Visual Studio用户界面中没有一种方式可以设置搜索的路径。(此外,对这些VSMDI文件来说没有理由被隐藏啊。)所以,当我想在一个不同的目录结构中使用VSMDI文件时,首先复制一个示例的VSMDI.OPTIONS文件到适当的目录,然后手动的编辑它,在程序集和TESTRUNCONFIG文件中添加路径。

为这一部分的源代码,我已经在BaseVSMDIOPTIONSFile文件夹中示例出了一个文件。

使用VSMDI文件主要的原因就是你可以指定要运行的测试列表-在动态开发过程中它是非常有用的,因为它允许你运行这些具体的测试,这些测试与你工作使用的代码相关。在一个测试集中要运行所有的测试,你可以使用控制台测试运行器,MSTEST.EXE。在这有大量的命令行选项,但是你仅仅需要”/testcontainer”选项,它指定了包含在测试中的程序集。另外,你可以使用”/resultfile”来指定结果文件的名称。当使用MSTEST.EXE时,你不必担心VSMDI文件。在下一部分,我将论述一个MSBuild.EXE任务,它可以自动的运行在目录结构中发现的所有测试,所以你可以避免和VSMDI文件一起使用。

你发现hardcoded路径的第二个位置就是在TESTRUNCONFIG文件中;指向instrument和strong key文件的程序集就包含hardcoded路径。我曾经指出了解决这个问题最好的办法就是当你在不同的目录结构下运行测试时使用一个不同的TESTRUNCONFIG文件。因为没有办法创建一个新的TESTRUNCONFIG文件,你需要复制一个已经存在的文件到机器位置,然后使用Visual Studio编辑它。如果驱动和上一级目录不同,IDE和MSTEST.EXE讲使用相关的路径来处理TESTRUNCONFIG文件,但是,你必须手动的编辑它们。

因为它本身不是做代码覆盖的测试工具,所以没有办法阻止为来自命令行的已经编译的程序集手动的执行代码覆盖。如果你使用ASP.NET进行工作,你需要从Visual Studio集成开发环境中做代码覆盖来创建合适的工具集,然后使它成为工具。

手动的做代码覆盖是一个三步的过程。第一步就是实现程序集以致你在它们中拥有代码覆盖钩(hooks)。第二步就是开始监视进程,然后告诉它在哪编写覆盖文件。任何在监视进程运行时加载的已经实现的二进制将它们的覆盖数据添加到输出文件。最后一步就是关闭监视,编写CONVERAGE文件。我已经制作出一个Converage.Targets文件,你可以和MSBuild一起使用来自动化这个过程。Figure 2显示出一些文件;您可以从MSDN®Magazine网站下载到全部的文件。

当你浏览Figure 2时,你将看到在Bugslayer.Build.Task.DLL中我写了一个任务来运行监视进程。Figure 3在Visual Studio中显示了它。

当首次编写Civerage.TARGETS时,我使用Exec任务执行VSPERFCMD /START:Coverage /OUTPUT:$(OutputCoverageFile),但是在做这时有一个严重的错误,MSBulid.EXE在调用时完全的挂起了。VSPERFCMD.EXE产生出了真实的监视进程,VSPERFMON.EXE。如果你在命令提示符下运行VSPERFMON.EXE,进程将待在那吐出连接和进程中其它活动的信息,所以你不能从项目文件中直接的调用它。

这个问题出现在MSBuild.EXE中,滋生于某个事件,这个事件就是VSPERFMON.EXE从带有bInheritHandles标记的VSPERFCMD.EXE进程中产生到CreateProcess,并且设置为“真”。任何带有继承句柄开始的进程将在MSBuild.EXE下挂起。因此,我必须在任务中从ITask.Execute方法调用Process.Start,通过这样操作才能使MSBuild.EXE下的所有事情正常运行。

与GenericTest和EXEs一起合作

如果你已经获得一个基于EXE程序的存在的测试系统,在文档中GenericTest类型的论述可能伤害您的好奇心。当在一个依赖运行九个EXE作为单元测试的批处理文件的项目上进行工作时,我可以使用GenericTest类型快速的包装一些自动化过程中存在的代码。虽然这也有一些catch。第一个小的障碍就是GenericTest允许0作为一个成功的来自EXE的返回值。那并不是一个很大的处理,但是考虑到GenericTest的高级特性,我很沮丧的看到与可接受的退出代码区域一样简单的事情被遗漏了。

GenericTest的一个比较大的问题就是它是hardcoding的一个堡垒。幸运地,可以容易地指出相对路径地文治。如果你地GenericTest存在C:\FOO中,事实上测试将从C:\FOO\TestResults\<User>_<Machine>_<TimeStamp>\Out开始。这样,如果被GenericTest执行地EXE文件在C:\FOO中,你可以使用./././<name>.EXE作为程序来执行。不幸地是,几乎GenericTest中地其他事情从驱动器中被硬编码。有趣地是外部目录就是你地二进制每次运行时被复制到地地方。即使你改变了代码,你可以重新运行测试地以前版本以重新生成问题。

一个便利地特性,GenericTest类型将捕获定位到标准输出地任何事情,在结果文件中提供一个运行日志。不幸的是,这看上去像是一个捕获的问题,在那提取一些信息将导致测试驱动进程挂起。但是大部分测试程序在几秒中内不会抽空输出结果中的100行。

巴中市中心医院怎么样
北京朝阳医院京西院区预约挂号
广州治牛皮癣好的医院
上海癫痫病医院去哪家好些
西宁治疗妇科医院哪家好
分享到: