我们已经使用 NUnit-NCover 完成了它,并且对我们的结果非常满意。
NUnit 执行之后是NUnitTfs 执行,以便在构建日志中发布我们的测试结果。然后 NCover 启动,生成我们的代码覆盖率结果。
造成不利影响的一件主要事情是,为正确调用 NCover 设置参数并非易事。但是自从我安装了它,我就再也不用维护它了。
有两个缺点:
- NUnitTfs 不适用于 NCover(至少我找不到在同一步骤中执行两者的方法,所以(因为 NCover 调用 NUnit)我必须运行单元测试两次:(1) 获得测试结果和 (2) 通过 NCover 获得覆盖率结果。自然,这使我的构建持续时间更长。
- 为正确调用 NCover 设置参数并非易事。但是自从我安装了它,我就再也不用维护它了。
无论如何,生成的报告(尤其是趋势方面)对于监控我们的代码如何随时间演变非常有用。特别是如果您在平台上工作(而不是短期项目),趋势报告非常有价值。
编辑
我将尝试以一种快速而肮脏的方式展示我是如何实现这一点的,希望它有用。目前,我们的构建服务器上有 NCover 3.4.12。
我们关于 NUnit 程序集的简单命名约定是,如果我们有一个生产程序集“123.dll”,则存在另一个名为“123_nunit.dll”的程序集来实现其测试。因此,每个构建都有几个感兴趣的 *_nunit.dll 程序集。
“如果不禁用测试”下的构建过程模板部分是为了实现我们的目标而重新设计的部分,特别是名为“为测试程序集运行 MSTest”的部分。整个实现是here,经过一些清理以使流程更易于理解(图片太大,无法直接插入此处)。
首先,在构建过程模板中实现了一些额外的参数,然后可以在每个构建定义中进行设置:
然后我们在“Formulate nunitCommandLine”中形成 NUnit 参数:
String.Format("{0} /xml={1}\\{2}.xml", nunitDLL, TestResultsDirectory, Path.GetFileNameWithoutExtension(nunitDLL))
然后在“Invoke NUnit”中使用它
如果成功并且我们已经为此构建设置了覆盖率,我们将转到“生成 NCover NCCOV”(此特定程序集的覆盖率文件)。为此,我们使用以下参数调用 NCover.Console.exe:
String.Format("""{0}"" ""{1}"" //w ""{2}"" //x ""{3}\{4}"" //literal //ias {5} //onlywithsource //p ""{6}""",
NUnitPath,
Path.GetFileName(nunitDLL),
Path.GetDirectoryName(nunitDLL),
Path.GetDirectoryName(Path.GetDirectoryName(nunitDLL)),
Path.GetFileName(nunitDLL).Replace("_nunit.dll", ".nccov"),
Path.GetFileNameWithoutExtension(nunitDLL).Replace("_nunit", ""),
BuildDetail.BuildNumber)
所有这些都在 foreach 循环“For all nunit dlls”中运行。当我们退出循环时,我们进入“Final NCover Activities” & 首先是“Merge NCCovs”部分,再次执行 NCover.Console.exe - 这次使用不同的参数:
String.Format("""{0}\*.nccov"" //s ""{0}\{1}.nccov"" //at ""{2}\{3}\{3}.trend"" //p {1} ",
Path.GetDirectoryName(Path.GetDirectoryName(testAssemblies(0))),
BuildDetail.BuildNumber,
NCoverDropLocation,
BuildDetail.BuildDefinition.TeamProject
)
当它运行时,我们已经达到了这样一个点:这个构建的所有 NCCOV 文件都被合并到一个以构建命名的 NCCOV 文件中 + 趋势文件(监控构建的整个生命周期)已经更新了元素当前版本的。
我们现在只需要生成最终的 HTML 报告,这是在“生成最终的 NCover 代表”中完成的,我们使用以下参数调用 NCover.reporting:
String.Format(" ""{0}\{1}.nccov"" //or FullCoverageReport //op ""{2}\{1}_NCoverReport.html"" //p ""{1}"" //at ""{3}\{4}\{4}_{5}.trend"" ",
Path.GetDirectoryName(Path.GetDirectoryName(testAssemblies(0))),
BuildDetail.BuildNumber,
PathForNCoverResults,
NCoverDropLocation,
BuildDetail.BuildDefinition.TeamProject,
BuildType
)