【问题标题】:Unit Testing Code Coverage单元测试代码覆盖率
【发布时间】:2014-12-11 14:26:56
【问题描述】:

我对代码覆盖率有点困惑。

示例: 我有一个方法,它有多个 if 语句(不是嵌套的),每个语句都附加到一个我完成后返回的字符串。

我的单元测试只是检查初始结果和最终结果,这是我为了这个问题而特意做的。中间什么都没有(所以不检查 else 语句)

问题: 如果我运行该测试,我将获得 100% 的代码覆盖率。我在理解这一点时遇到的问题是我想要方法本身的代码覆盖率,而不是我的测试有多少被命中。由于没有命中 else 语句,它应该会低一些。

我查看了有关单元测试和代码覆盖率的各种教程和 msdn。在某些情况下,测试似乎是从方法本身分析代码(我想做的),但在大多数其他情况下,它只检查测试的代码覆盖率。

我的问题是; 有没有办法将测试链接到方法,以便在我分析测试代码覆盖率时获得方法的代码覆盖率,或者这就是代码覆盖率的目的,用户必须编写测试来解决这些问题分支机构?

感谢您的宝贵时间。

编辑:代码示例。

public static string testingString(string s1, string s2, bool isAllowed, bool isAdmin, bool isCustomer){
    string result = string.Format("{0}/{1}", s1, s2);
    if (isAllowed) result += "/Allowed";
    if (isAdmin) result += "/admin";
    if (isCustomer) result += "/customer";
    return result;
}

测试:

[TestMethod]
public void testingString_BasicTest()
{
    var result = testingString("test1", "test2", false, false, false);
    var expectedResult = string.Format("{0}/{1}", "test1", "test2");

    Debug.WriteLine("Result should be: " + expectedResult);
    Assert.AreEqual(expectedResult, url);
}

testingString_BasicTest 在这种情况下将有 100% 的代码覆盖率,尽管没有达到 3 个 if 语句结果。

【问题讨论】:

  • 一个代码示例在这里可能会有所帮助:)
  • 这获得了 100% 的代码覆盖率? [您实际上使用覆盖工具运行了这个并查看了报告?] 使用什么工具 [大概是 VS2013]?它可能会获得 100% 的 line 覆盖率;函数中的每一行 line 都会被执行。但很明显,并不是每个 statement 都会被执行。使用 false/false/false,“result += ....”语句显然不会执行。
  • ...还需要注意工具限制。许多字节码检测器只能将代码解析到“行”级别,因为字节码最多可以跟踪行号。如果行中的任何语句的任何部分被执行,则按 line 跟踪语句的“语句覆盖”工具实际上可能会混淆“行”被完全覆盖的报告。如果一行中有多个语句,并且您希望能够将它们区分开来,则需要一种更精细的工具来报告语句覆盖率。
  • testingString_BasicTest 将显示 100% 的代码覆盖率,因为测试的每一行都已执行。那不重要。重要的是为 testingString 显示的代码覆盖率对于该方法,您应该看到大约 50% 的代码覆盖率与您的测试。

标签: c# unit-testing visual-studio-2013 code-coverage


【解决方案1】:

代码覆盖率是指在测试执行中执行代码。它实际上与测试的内容没有任何关系,只是在您的测试运行时执行。

如果在测试过程中的任何时候都执行了该方法中的每个命令,代码覆盖率将返回 100%。如果您想查看单个测试的代码覆盖率(使用 VS 2013 Ultimate 代码覆盖率工具),请在“测试管理器”窗口中选择它,然后单击“测试/分析代码覆盖率/选定测试”以查看该特定测试涵盖的内容。

【讨论】:

  • 这个答案极具误导性;它假定“代码覆盖率”===“行覆盖率”。有很多种测试覆盖率;请参阅en.wikipedia.org/wiki/Code_coverage 了解最常用的术语。 OP 想要的是更像“声明覆盖率”的东西。
  • 语句“如果在测试过程中的任何时候执行该方法中的每个命令,代码覆盖率将返回 100%。”旨在传达每行上的每个语句都被触及,而不仅仅是每一行都被触及。我熟悉的所有代码覆盖率工具都不会在不执行每条语句的情况下显示 100% 的代码覆盖率。
【解决方案2】:

根据您的更新,由于您构建代码的方式,您将获得 100% 的覆盖率。所有行都被命中,事件虽然不是所有的代码路径都被执行。如果您像这样重组代码,那么您将不再获得 100% 的覆盖率:

public static string testingString(string s1, string s2, bool isAllowed, bool isAdmin, bool isCustomer){
    string result = string.Format("{0}/{1}", s1, s2);
    if (isAllowed) 
    {
        result += "/Allowed";
    }
    if (isAdmin) 
    {
        result += "/admin";
    }
    if (isCustomer) 
    {
        result += "/customer";
    }
    return result;
}

有些工具会比其他工具更好地处理这个问题(我相信 JetBrains dotCover 不会报告您的版本已被覆盖)但有些工具只是查看执行的代码是否在线,因为看起来 Visual Studio 工具正在执行,所以它看到 if() 正在执行,并认为整行都被覆盖了。

【讨论】:

  • 这是在单独的行上强制单独的语句,从而试图使“行覆盖”===“语句覆盖”。我不知道 MS 工具是否真的成功了; "{" 和 ""}" 是否也标记为 line-covered?(使用 XDebug 的标准 PHP 工具同样存在无法计算 "}" 的 line-coverage 的问题,也是因为它只能访问“行号”和“}”不在字节码中)。
猜你喜欢
  • 2012-01-18
  • 2023-04-07
  • 1970-01-01
  • 2010-10-14
  • 2013-04-16
  • 2014-12-10
  • 1970-01-01
相关资源
最近更新 更多