我们都知道之所以用Team Build是为了进行持续集成,并且能够更好的保证整个team不被其它的明显故障所耽误。Team Build在背后是用了MSBuild进行对项目的编译,这和在我们的Visual Studio中进行编译是一样的道理。但我们在Visual Studio中进行编译解决方案的时候,默认情况下是无法对Unit Test进行逐个或者分类运行来达到对代码的单元测试的目的,而在Team Build中我们却可以在Build Definition中定义是否运行Unit Test,更高级的我们还可以定义对哪些符合条件的Unit Test运行来达到对代码的检查并保证签入TFS Source Control的代码质量。Team Build还可以通过对Unit Test的执行结果的分析计算出Code Coverage,这也是对我们项目管理中非常有用的数据。
是否运行Unit Test及对Unit Tests的过滤都是在Build Definition中进行设置的。要修改对这些设置的改变,右键点击这个Build Definition并选择Edit Build Definition,在打开的窗口中选择Process栏目,所有的设置都可以在这里进行更改。
Figure 1 - 在Build Definition中对相关的构建设置进行更改
运行指定程序集中的单元测试
通常情况下,我们都将单元测试作为单独的项目,其中根据不同的测试对象而分成不同的组来进行组织,这也是Visual Studio的默认组织方式--当你点击某个方法自动生成单元测试时会询问是否添加新的测试项目或者附加到已有的测试项目中去。而对于很多企业来说,对于项目的命名方式也有着严格的标准,在这个时候你就会发现有标准命名是多么高兴的一件事情。如果你想让Team Build在编译完项目后同时运行某些Assembilies中的Unit Tests,你可以设置一个含有通配符的过滤条件来达到这个目的。对Test Assembly Filespec参数设置含有通配符的过滤条件便达到指定测试程序集范围的目的。
Figure 2 - 设置Unit Test程序集的范围
对于那些没有统一命名规范的公司来讲,现在是时候考虑使用统一的命名规范对你的项目和命名空间进行约束了:)
除了可以选择要执行的单元测试程序集,你现在还可以进一步通过对Unit Test的优先级别进行过滤来确定执行Test的范围。其实Unit Test的优先级(Test Priority)在.NET2.0的时候就出现了,可是一直没有被Visual Studio和Team Build所采纳。但在Team Build 2010中我们发现Test Priority被支持了。那如何给Unit Test设置优先级别呢?
[TestCategory("Web Service")] [TestCategory("ASP.NET")] [CssProjectStructure("vstfs:///Classification/Node/0eed9522-47f8-4fa1-891d-0b14629d47f0")] [Owner("Allan Zhou")] [CssIteration("vstfs:///Classification/Node/65610ebf-7f79-46f4-931f-89ac54bfc15f")] [AspNetDevelopmentServer("SSW.SqlDeploy.WebServices.Host", "%PathToWebRoot%\\SSW.SqlDeploy.WebServices.Host")] [DeploymentItem("SSW.SqlDeploy.WebServices.Host.dll")] [Priority(1)] [TestMethod] // [Ignore] //Ignore this test on the build server as the self-hosted web site won't start automatically. public void UpdateProjectFileTest() { ProfileService target = new ProfileServiceClient(); Assert.IsTrue(WcfWebServiceHelper.TryUrlRedirection(target, TestContext, "SSW.SqlDeploy.WebServices.Host")); target.SaveDefaultProjectFile("testWen"); ProjectFile projectFile = new ProjectFile(); projectFile.ProjectFileName = "testWen"; projectFile.NewDatabase = true; bool isFalse = target.UpdateProjectFile(projectFile); Assert.AreEqual(false, isFalse); }
注意了,在上边的一长串的标记中我们启用了[Priority(1)]这样的标记,它就是用来设置当前Unit Test的优先级的。注意Priority的参数是整数,这意味着你可以设置任意的数字,但需要记住,最好是有限的几个数字,否则过多的级别设置会让它失去用处。我们建议使用1-5来定义优先级别。
现在,Unit Test本身有了Test Priority,那在Build Definition中怎么限制呢?在下图中我们可以看到两个参数Minimum Test Priority和Maximum Test Priority,它们一起定义了符合运行条件的优先级区间,如果为-1表示没有限制。
Figure 3 - 设置test Priority区间
出了优先级,每个Unit Test还可以具有一个或多个类别,而这些都是可以被Team Build拿来作为运行Unit Test的过滤条件来使用的。这和Test Priority很像,您给每个Unit Test划分了具有意义的名称类别并将它应用到测试方法本身,而在这里你将可以通过匹配类别来达到限制运行Unit Test的目的。要使用这种方法,必须给Unit Test添加TestCategory标记,并给予有意义的名称类别。注意,一个Unit Test可以设置多个Test Category.
在Category FIlter参数中我们可以设置运行Unit test的过滤条件。注意,在此参数中我们可以使用逻辑操作符如&, !和| 来构筑过滤条件。
Figure 4 - 设置Unit Test类别过滤条件
当您运行单元测试时,通常我们想知道被测试的代码有多少是被真正测试过的,又名代码覆盖率。在Visual Studio 2010的解决方案中,默认都有一个.testsettings文件,之前我们也提到了,这个文件是用来设置对项目进行测试和分析的各种参数的。奇怪的IntelliTrace的问题也是在这里被找到的。也就是说,在Team Build对项目编译之后的所有分析、运行测试用例等等都是在这里进行设置的。双击打开TraceAndTestImpact.testsettings文件我们可以在Data and Diagnostics栏中找到相关信息。
选择Code Coverage项我们将会在Team Build的Summary页上看到有关Code Coverage的信息。点击Configure按钮我们还可以对参照对象进行更改(因为所谓代码覆盖率只是相对于某个范围的代码,单元测试所能覆盖到的范围,这是相对的)。
默认情况下,代码覆盖率的参照条件是测试方法所测试的真实方法所在的项目。如上图所示,三个被默认选中的项目是具有单元测试的当项目,这些单元测试将对这三个项目中的方法进行调用并进行测试,所以以它们作为基准来作为参照物。
当你的Team Build运行完你可以在Build Summary中得到相关的信息: