【问题标题】:Are there any code coverage tools that allow me to exclude code by line?是否有任何代码覆盖工具允许我逐行排除代码?
【发布时间】:2015-08-14 14:48:44
【问题描述】:

我想要的,来自 .NET 覆盖工具,但一直找不到...

能够运行单元测试,并跟踪哪些单元测试已经执行了哪些代码行,以及哪些代码行根本没有执行。 能够生成交互式报告,允许用户按程序集、文件、命名空间、类等查看覆盖率的统计摘要;并深入到源代码级别以准确查看哪些行被覆盖和未被覆盖。

能够运行测试并从 Jenkins 生成报告,并将报告包含在 Jenkins 为每个构建显示的信息中。 能够按行将源代码标记为不需要覆盖。 能够让报告清楚地表明每一行源代码都已被覆盖或标记为不需要覆盖。

我一直在寻找免费的覆盖工具,但并不满意。我最近开始阅读 dotCover,它看起来确实提供了我需要的更多内容。但从我在文档中读到的内容来看,它提供了将代码从文件、类或函数的覆盖要求中排除的机制。但如果它提供了按行从覆盖范围中排除代码的功能,我就错过了。

本质上,我正在寻找的是通过失败。 90% 的覆盖率,80% 的覆盖率,或者 95% 的覆盖率,对我来说毫无意义。 80% 的覆盖率可能意味着 20% 的代码不需要覆盖率,99.9% 的覆盖率可能意味着只有一个迫切需要测试的关键功能尚未测试。

我的看法分为三类:

  1. 已被测试覆盖的代码
  2. 已标记为不需要测试的代码
  3. 未被测试覆盖且未被标记为不需要测试的代码

在单元测试运行之后,如果没有第 3 类中的代码,我想要的是通过,或者如果有,则失败。

而且我需要能够将代码标记为不需要逐行测试,而不仅仅是函数测试,因为当我查看覆盖率报告中的函数时,我很容易看到某些控制流通过测试未执行的功能。最常见的是异常或错误处理。有时,创建将生成测试这些控制流所需的错误或异常的测试所需的工作量可能很大,而有时测试揭示问题的可能性很小。

在这种情况下,我希望能够将代码标记为已检查,并且已确定不需要测试。当我以这种方式标记代码时,我希望代码未被测试覆盖的事实不会导致构建失败。

有谁知道有什么 NET 覆盖工具可以做到这一点?

【问题讨论】:

  • 官方工具请求在 Stack Overflow 上是题外话。至于您的问题,随着类/方法的变化,排除特定的行并随着时间的推移排除该确切的行并不容易。维护将是地狱般的。它可能更像是您正在寻找的代码审查工具,它也可以突出显示覆盖率信息,而不是覆盖率工具。
  • 如果 Stack Exchange 元社区中有更好的地方问这个问题,请告诉我,我会移动它。
  • 我不认为有问这个问题的好地方。我认为,如果您将其改写为就如何执行此审查寻求实践或建议,那么它会很合适,但是对于程序员以及 stackoverflow 和代码审查而言,寻求工具建议是禁区...
  • @jessehouwing 为什么维护起来会很糟糕?您可以通过让该工具读取源代码中的 pragma cmets 来做到这一点,就像 coverage.py 所做的那样。
  • @jessehouwing Software Recommendations 怎么样?

标签: .net unit-testing jenkins code-coverage


【解决方案1】:

OpenCover 将允许您按行(序列点)跟踪覆盖率,如果您使用-coverbytest,您可以确定当行被击中时正在运行哪个测试。

没有按行排除功能,因为 OpenCover 在您的程序集运行时对其进行检测,并且不知道实际的代码行。您可以编写自己的工具来删除您希望排除的行的结果,方法是解析代码,然后在使用ReportGenerator 生成报告之前从结果中删除任何序列点。

但是有人会说没有代码是不可测试的,您只需要以不同的方式重新构建它。通常这种代码是人们说他们不能测试的,因为他们不能强制异常。

public void Method()
{
  try
  {
    // do something
  }
  catch (Exception ex)
  {
    // respond to exception
  }
}

但要对此进行测试,您只需将其分解为更小的部分

internal void TryCatch<T>(Action doAction, Action<T> catchAction) where T : Exception { 
  try { doAction(); } catch (T ex) { catchAction(ex); }
}

internal void DoMethod() {
  // do something
}

internal void CatchMethod(Exception ex){
  // respond to exception
}

public void Method() {
  TryCatch<Exception>(DoMethod, CatchMethod);
}

现在每个部分都可以单独测试,而无需隐藏任何代码(如果您愿意的话)。例如在TryCatch&lt;T&gt;() 的情况下,您可以测试如果doAction 引发异常,则调用catchException 操作,或者您可以将方法排除在覆盖范围之外,因为它是如此微不足道。

我很少采用这种模式方式,除非我真的需要测试在某些条件下调用 catch 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    相关资源
    最近更新 更多