【问题标题】:TFS Build 2010 Code Coverage using NUnit使用 NUnit 的 TFS 构建 2010 代码覆盖率
【发布时间】:2012-02-23 02:06:24
【问题描述】:

我想知道你们中是否有人在运行 NUnit 测试时有在 TFS Build Server 2010 中生成代码覆盖率报告的经验。

我知道使用打包的替代方案(MSTest + 在 testrunco​​nfig 文件上启用覆盖)可以轻松完成,但使用 NUnit 时会涉及更多问题。我在这里和那里找到了一些指向 NCover 的信息,但它似乎已经过时了。我想知道是否还有其他替代方案,以及是否有人实际实施了这一点。

以下是有关我们的环境/需求的更多信息: - TFS 构建服务器 2010 - 测试在普通类库中(不是测试库 - 即没有关联的 testrunco​​nfig 文件),并在 NUnit 中实现。我们没有 MSTest。 - 我们有兴趣在每个构建过程中运行覆盖率报告,并在可能的情况下为通过/失败标准设置覆盖率阈值要求。

【问题讨论】:

    标签: nunit code-coverage


    【解决方案1】:

    我们已经使用 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
                  )
    

    【讨论】:

    • 谢谢!我们很快就会尝试这个。必须运行两次测试似乎有点痛苦,但我愿意为报告目的付出代价。我敢肯定,如果需要,我们可以想办法并行运行它们。几个后续问题:(1)您有任何可以分享的设置资源吗? (2) 您是否为您的覆盖率设置了任何构建失败/通过标准(例如,当覆盖率
    • 您好,rtorres,很高兴为您服务!我目前正在休假,因此我对资源的访问权限有限——几周后提供帮助是没有问题的。关于 (2):不,我没有,因为我战略性地将代码覆盖率视为我们代码质量的“软”指标 - 我相信如果你需要它可以做到这一点。
    • 太好了,感谢您的帮助。关于#2,是的,我同意,覆盖率不是直接的质量指标。我们希望更多地设置这些阈值,以帮助我们改善开发团队的测试习惯(我们从 0% 开始,因此希望避免滑倒)。
    • 感谢更新!上次我尝试这样做时,我无法让它工作。我很快就会检查出来。
    • 您是否知道如何将 NCover 结果发布到 TFS 以便它显示在构建摘要报告中?
    猜你喜欢
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多