在目前的VSTS 2008中并不支持非托管代码的单元测试,需要采用第三方的测试工具,比如WinUnit,但是如何在Team Build中集成WinUnit的测试过程和结果呢?一般来说可以在测试工程的Post Build Event中加入命令行的调用,但是这种做法有几个缺点,一是如果单元测试失败,则整个Team Build就失败了;二是无法在Team Build的Detail中展现单元测试结果;三是无法展示Code Coverage的结果,有更好的方法吗?
答案是肯定的,不过操作起来有些麻烦,我们需要采用Generic Test来实现对第三方测试工具的封装,具体的做法如下:
第一步,建立一个C++的Test Project,可以取名为UnitTestWrapper。
第二步,在UnitTestWrapper中加入一个个的Generic Test,每个Test对应一个WinUnit的测试dll,每个Test的设置可参考后面的步骤。
第三步,修改SolutionName.vsmdi设置,这个文件很怪,不能改名,不能挪位置,只能放在sln文件旁边,把刚才New出来的Generic Test拖拽到Lists of Tests下面的Test List中。
第四步,修改TFSBuild.proj文件,加入一个环境变量的设置插件,并打开测试开关,请注意,把WinUnit.exe和SetEnvVarTask.dll这两个文件放入TFSBuild.proj文件所在目录。
<UsingTask
TaskName="SetEnvVarTask"
AssemblyFile="SetEnvVarTask.dll"/>
......
<!-- RunConfigFile
Run config of generic tests.
-->
<RunConfigFile>$(SolutionRoot)/Tests/KernelUnitTestWrapper/LocalTestRun.testrunconfig</RunConfigFile>
......
<!-- MetaDataFile和LocalMetaDataFile都要定义,这样服务器Build和DesktopBuild才能都运行测试。 -->
<MetaDataFile Include="$(SolutionRoot)/Kernel.vsmdi">
<TestList>Kernel Unit Tests</TestList>
</MetaDataFile>
<LocalMetaDataFile Include="$(SolutionRoot)/Kernel.vsmdi">
<TestList>Kernel Unit Tests</TestList>
</LocalMetaDataFile>
......
<!-- 定义UnitTest使用的改环境变量 -->
<Target Name="BeforeTest">
<SetEnvVarTask
NewEnvVars="SolutionRoot=$(SolutionRoot);
OutDir=$(OutDir);
WinUnitApp=$(SolutionRoot)/__TeamBuild/Kernel_Build/WinUnit.exe"/>
</Target>
第五步,修改发布路径Drop Location的权限,把Network Service这个账号设为共享和安全的完全控制,记住,一定要完全控制,否则发布测试结果会失败。
第六步,修改LocalTestRun.testrunconfig文件,加入Code Coverage相关设定:
<CodeCoverage enabled="true">
<Regular>
<CodeCoverageItem binaryFile="%OUTDIR%Bin/TestBase.dll" pdbFile="%OUTDIR%Symbol/TestBase.pdb" instrumentInPlace="true" />
</Regular>
</CodeCoverage>
第七步,记得修改你的待测试工程,把所有的调试信息都加上,比如Lib库需要定制输出的pdb文件,然后打开Profile开关。
好了,你现在可以启动一次Team Build来测试一下结果了,如果成功的话你将会看到: