单元测试中的指标

单元测试覆盖率是衡量测试代码对应用代码覆盖程度的指标,常用的覆盖率指标包括 statements(语句)branches(分支)functions(函数)lines(行)。以下是这些指标的具体含义:

1. Statements(语句覆盖率)

  • 定义:统计被执行的代码语句占总语句的比例。
  • 示例
    1
    2
    3
    4
    function sum(a, b) {
    const result = a + b; // 语句1
    return result; // 语句2
    }
    • 覆盖率计算:若测试执行了 sum(1, 2),则两条语句均被执行,语句覆盖率为 100%。

2. Branches(分支覆盖率)

  • 定义:统计代码中每个条件分支(如 if/else、三元运算符、switch)是否被执行。
  • 示例
    1
    2
    3
    4
    5
    6
    7
    function checkNumber(n) {
    if (n > 0) { // 分支1:true/false
    return 'positive'; // 分支1-true
    } else {
    return 'non-positive'; // 分支1-false
    }
    }
    • 覆盖率计算
      • 若测试仅执行 checkNumber(1),则只覆盖了 n > 0true 的分支,分支覆盖率为 50%。
      • 若测试同时执行 checkNumber(1)checkNumber(-1),则覆盖所有分支,分支覆盖率为 100%。

3. Functions(函数覆盖率)

  • 定义:统计代码中每个函数是否被调用。
  • 示例
    1
    2
    function add(a, b) { return a + b; }  // 函数1
    function multiply(a, b) { return a * b; } // 函数2
    • 覆盖率计算
      • 若测试仅调用 add(1, 2),则函数覆盖率为 50%。
      • 若测试同时调用 add(1, 2)multiply(2, 3),则函数覆盖率为 100%。

4. Lines(行覆盖率)

  • 定义:统计被执行的代码行占总行数的比例。
  • 示例
    1
    2
    3
    4
    5
    6
    7
    function calculate(n) {
    if (n > 0) { // 行1
    return n * 2; // 行2
    } else {
    return n / 2; // 行3
    }
    }
    • 覆盖率计算
      • 若测试仅执行 calculate(1),则行覆盖率为 67%(行1和行2被执行,行3未执行)。
      • 若测试同时执行 calculate(1)calculate(-1),则行覆盖率为 100%。

为什么需要关注这些指标?

  • 语句覆盖率:确保代码中的每一行都被执行,但可能遗漏分支逻辑。
  • 分支覆盖率:验证所有条件分支是否被测试,避免逻辑漏洞(如 if/else 只测了一种情况)。
  • 函数覆盖率:确保所有函数都被调用,避免未使用或未测试的代码。
  • 行覆盖率:与语句覆盖率类似,但可能受代码格式影响(如一行包含多个语句)。

示例对比

假设代码如下:

1
2
3
4
function isAdult(age) {
if (!age) return false; // 分支1(age为空)
return age >= 18; // 分支2(age>=18)
}
  • 测试用例1isAdult(20)

    • 语句覆盖率:100%(两行都执行)
    • 分支覆盖率:50%(只覆盖了 age >= 18true 分支,未覆盖 false 分支)
  • 测试用例2isAdult(20)isAdult(15)

    • 语句覆盖率:100%
    • 分支覆盖率:100%(覆盖了 age >= 18truefalse 分支)

最佳实践

  • 优先关注分支覆盖率:它能发现条件逻辑中的潜在漏洞。
  • 结合多种覆盖率指标:单一指标无法全面评估测试质量。
  • 避免过度追求100%覆盖率:某些代码(如错误处理、边缘情况)可能难以或无需测试。

工具支持

常见的覆盖率工具(如 Istanbul、Jest、Cobertura)会生成详细的覆盖率报告,展示各项指标的覆盖情况。例如:

1
2
3
4
5
----------------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------------------|---------|----------|---------|---------|-------------------
src/game.js | 100 | 100 | 100 | 100 |
----------------------------|---------|----------|---------|---------|-------------------

通过分析这些指标,你可以针对性地补充测试用例,提高测试质量。