← 返回首页

📊 测试覆盖率指南

Jest Coverage Metrics 详解

覆盖率的四种计算口径

Jest 测试覆盖率使用 Istanbul (nyc) 作为底层引擎,提供4种不同维度的覆盖率指标:

口径 英文 含义 计算公式
语句覆盖率 Statements 代码语句被执行的比例 已执行语句数 / 总语句数
分支覆盖率 Branches 条件分支被覆盖的比例 已覆盖分支数 / 总分支数
函数覆盖率 Functions 函数被调用的比例 已调用函数数 / 总函数数
行覆盖率 Lines 代码行被执行的比例 已执行行数 / 总行数

各口径详解

📝 语句覆盖率 (Statements)

衡量代码中的语句是否被执行。一行代码可能包含多个语句。

// 这是 1 行,但包含 2 个语句
let x = 1; let y = 2;

// 这是 1 行 1 语句
const sum = x + y;
🔀 分支覆盖率 (Branches) - 最严格

衡量条件语句的每个分支是否都被测试。这是最重要的指标,因为它确保了逻辑的完整性。

// 有 2 个分支:if 为真 和 if 为假
if (user.isAdmin) {
  grantAccess();    // 分支 1
} else {
  denyAccess();     // 分支 2
}

// 三元运算符也有 2 个分支
const status = isActive ? 'active' : 'inactive';

// switch 语句每个 case 都是一个分支
switch (type) {
  case 'A': ... // 分支 1
  case 'B': ... // 分支 2
  default: ...  // 分支 3
}
🔧 函数覆盖率 (Functions)

衡量函数是否被调用过。不关心函数内部逻辑是否完整覆盖。

// 只要这个函数被调用一次,函数覆盖率就是 100%
function calculateTotal(items) {
  if (items.length === 0) return 0;  // 分支可能未覆盖
  return items.reduce((sum, i) => sum + i.price, 0);
}
📏 行覆盖率 (Lines)

衡量代码行是否被执行。与语句覆盖率类似,但以行为单位。

项目配置的覆盖率阈值

60%
Backend 所有指标
70%
Frontend 所有指标

后端配置 backend/jest.config.js

coverageThreshold: {
  global: {
    branches: 60,
    functions: 60,
    lines: 60,
    statements: 60
  }
}

前端配置 frontend/web_app/jest.config.js

coverageThreshold: {
  global: {
    branches: 70,
    functions: 70,
    lines: 70,
    statements: 70
  }
}

如何查看覆盖率报告

命令行查看

# 后端覆盖率
cd backend && npm run test:coverage

# 前端覆盖率
cd frontend/web_app && npm run test:coverage

# 根目录快捷命令(后端+前端)
npm run test:coverage

HTML 报告(推荐)

运行覆盖率测试后,会在 coverage/ 目录生成 HTML 报告:

# 打开后端覆盖率报告
open backend/coverage/lcov-report/index.html

# 打开前端覆盖率报告
open frontend/web_app/coverage/lcov-report/index.html
💡 HTML 报告功能

输出示例

-----------------------------|---------|----------|---------|---------|
File                         | % Stmts | % Branch | % Funcs | % Lines |
-----------------------------|---------|----------|---------|---------|
All files                    |   85.23 |    72.15 |   91.45 |   85.67 |
 services/                   |   92.34 |    84.21 |   95.00 |   92.56 |
  auditLogger.js             |   97.05 |    76.47 |  100.00 |  100.00 |
  checkinService.js          |  100.00 |    87.69 |  100.00 |  100.00 |
  invoiceService.js          |  100.00 |    98.21 |  100.00 |  100.00 |
-----------------------------|---------|----------|---------|---------|

哪个指标最重要?

⚠️ 分支覆盖率 (Branches) 是最关键的指标

即使语句/函数/行覆盖率都是 100%,分支覆盖率可能只有 50%。

这意味着你的代码逻辑只测试了一半的情况,另一半可能隐藏着 bug。

// 示例:语句覆盖 100%,分支覆盖 50%
function getDiscount(customer) {
  if (customer.isVip) {
    return 0.2;  // ✅ 被测试了
  }
  return 0;      // ❌ 从未被测试!
}

// 只写了这个测试
test('VIP gets 20% discount', () => {
  expect(getDiscount({ isVip: true })).toBe(0.2);
});

CI 门禁检查

项目配置了 .github/workflows/ci-test.yml 在 PR 时自动检查覆盖率:

🧪 统一测试系统 (Unified Test Runner)

项目提供统一测试运行器,可一次性运行所有子项目的测试,覆盖 465+ 个测试文件

测试文件统计

项目 类别 文件数 框架
Backend 单元/API/集成测试 252+ Jest
Frontend 单元 + E2E 测试 173 Jest + Playwright
Landing 单元 + E2E 测试 3 Vitest + Playwright
Guest App 单元 + E2E 测试 23 Flutter Test
Employee App 单元 + E2E 测试 14 Flutter Test

统一测试命令

# 日常自检(推荐)- 后端 + 前端 + Landing
npm run test:all

# 快速测试(提交前)- 仅单元测试
npm run test:all:quick

# 完整测试(发布前)- 含 Flutter 移动端
npm run test:all:full

# CI 模式 - 含覆盖率报告
npm run test:all:ci

# 按测试类型
npm run test:all:unit         # 仅所有单元测试
npm run test:all:integration  # 仅所有集成测试
npm run test:all:e2e          # 仅所有 E2E 测试

脚本参数详解

直接调用脚本 ./scripts/test-all.sh [options] 支持更多选项:

参数 说明
--backend仅后端测试
--frontend仅前端测试
--landing仅 Landing Page 测试
--flutter仅 Flutter 移动端测试
--guest-app仅 Guest App 测试
--employee-app仅 Employee App 测试
--unit仅单元测试
--integration仅集成测试
--e2e仅 E2E 测试
--quick快速模式(跳过慢测试)
--ciCI 模式(含覆盖率报告)
--full完整模式(含移动端)
--verbose详细输出
--report生成汇总报告(默认开启)

测试报告目录

test-reports/
├── backend/                   # 后端测试报告
│   ├── unit/
│   ├── integration/
│   ├── api/
│   └── sync/
├── frontend/                  # 前端测试报告
│   ├── unit/
│   └── e2e/
├── landing/                   # Landing Page 测试报告
├── flutter/                   # 移动端测试报告
│   ├── guest-app/
│   └── employee-app/
└── summary/                   # 汇总报告
    └── latest.md              # 最新汇总报告(符号链接)
💡 查看汇总报告
cat test-reports/summary/latest.md

Flutter E2E 测试命令

Guest App 的 Flutter E2E 测试也可以单独运行:

# 运行所有 Flutter E2E 测试
npm run test:flutter

# 按模块运行
npm run test:flutter:auth       # 认证流程
npm run test:flutter:booking    # 预约流程
npm run test:flutter:cart       # 购物车流程
npm run test:flutter:appointments # 预约列表
npm run test:flutter:account    # 账户/设置
npm run test:flutter:config     # AppConfig 动态配置
⚠️ Flutter 测试需要设备

Flutter 集成测试需要连接 iOS Simulator 或 Android Emulator。

如果检测到多个设备,需要指定设备:flutter test integration_test/ -d <device_id>

📅 更新于 2026-02-06