前端项目测试覆盖率检测

背景介绍

什么是测试覆盖率?

测试覆盖率(Test Coverage)是衡量代码被测试用例覆盖程度的指标。它帮助开发者了解:

  • 哪些代码已被测试:确保关键功能有测试保护
  • 哪些代码未被测试:识别测试盲点,发现潜在风险
  • 代码质量趋势:通过覆盖率变化评估代码质量改进情况

测试框架

本文使用 Jest 作为测试框架,配合 ts-jest 支持 TypeScript 测试。Jest 提供了内置的覆盖率收集功能,无需额外配置即可生成详细的覆盖率报告。


前提条件

安装所有必要的依赖,包括:

  • jest - 测试框架
  • ts-jest - TypeScript 支持
  • @jest/globals - Jest 全局类型
  • jest-environment-jsdom - DOM 环境支持
  • @types/jest - TypeScript 类型定义

验证依赖安装

检查 node_modules 目录是否存在,或运行:

bash 复制代码
pnpm list jest ts-jest

项目配置

Jest 配置文件

  • 文件位置jest.config.ts(项目根目录)

配置参考:

typescript 复制代码
import type { Config } from 'jest';

const config: Config = {
  // 使用 ts-jest 预设
  preset: 'ts-jest',

  // 测试环境
  testEnvironment: 'jsdom',

  // 根目录
  rootDir: '.',

  // 测试文件匹配模式
  testMatch: [
    '**/__tests__/**/*.test.ts',
    '**/__tests__/**/*.test.tsx',
    '**/?(*.)+(spec|test).ts',
    '**/?(*.)+(spec|test).tsx'
  ],

  // 模块文件扩展名
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],

  // 模块路径映射(根据项目结构调整)
  moduleNameMapper: {
    '^xxxx$': '<rootDir>/packages/xxxx/src',
    '^@xxxx/(.*)$': '<rootDir>/packages/xxxx/src/$1',
  },

  // 转换配置
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        tsconfig: {
          // 测试环境需要的额外配置
          module: 'commonjs',
          esModuleInterop: true,
          allowSyntheticDefaultImports: true,
          target: 'ES5',
          strict: true,
          skipLibCheck: true,
          moduleResolution: 'node',
          sourceMap: true,
        },
      },
    ],
  },

  // 覆盖率配置
  collectCoverageFrom: [
    'packages/**/src/**/*.{ts,tsx}',
    '!packages/**/src/**/*.d.ts',
    '!packages/**/src/**/__tests__/**',
    '!packages/**/src/**/*.test.{ts,tsx}',
    '!packages/**/src/**/index.ts', // 通常不测试入口文件
  ],

  // 覆盖率报告目录
  coverageDirectory: '<rootDir>/coverage',

  // 覆盖率阈值(可选,根据需要调整)
  // coverageThreshold: {
  //   global: {
  //     branches: 80,
  //     functions: 80,
  //     lines: 80,
  //     statements: 80,
  //   },
  // },

  // 忽略的目录
  testPathIgnorePatterns: [
    '/node_modules/',
    '/dist/',
    '/coverage/',
  ],

  // 清除 mock
  clearMocks: true,

  // 恢复 mock
  restoreMocks: true,

  // 显示覆盖率
  collectCoverage: false,

  // 详细输出
  verbose: true,
};

export default config;

TypeScript 配置

  • 文件位置tsconfig.json(项目根目录)
  • 要求 :启用 strict: true 模式

package.json 脚本

  • 文件位置package.json(项目根目录)

  • 要求 :包含 test:coverage 脚本

  • 当前配置

    json 复制代码
    {
      "scripts": {
        "test:coverage": "jest --coverage"
      }
    }

快速开始

1. 运行覆盖率检测

在项目根目录执行以下命令:

bash 复制代码
# 生成覆盖率报告
pnpm test:coverage

# 或者只测试 xxxx 包
pnpm test:xxxx --coverage

2. 查看覆盖率报告

运行完成后,覆盖率报告会生成在 coverage/ 目录下:

  • HTML 报告 :打开 coverage/lcov-report/index.html 在浏览器中查看详细的覆盖率报告
  • 终端输出:命令执行完成后,会在终端显示覆盖率摘要

3. 覆盖率指标说明

Jest 会报告以下四个覆盖率指标:

  • Statements(语句覆盖率):已执行的语句百分比
  • Branches(分支覆盖率):已执行的分支(if/else、switch 等)百分比
  • Functions(函数覆盖率):已调用的函数百分比
  • Lines(行覆盖率):已执行的行百分比

当前配置

项目已配置了 Jest 覆盖率收集,配置位于 jest.config.ts

typescript 复制代码
// 覆盖率配置
collectCoverageFrom: [
  'packages/**/src/**/*.{ts,tsx}',
  '!packages/**/src/**/*.d.ts',
  '!packages/**/src/**/__tests__/**',
  '!packages/**/src/**/*.test.{ts,tsx}',
  '!packages/**/src/**/index.ts', // 通常不测试入口文件
],

// 覆盖率报告目录
coverageDirectory: '<rootDir>/coverage',

包含的文件

  • packages/**/src/**/*.{ts,tsx} - 所有 TypeScript 源文件

排除的文件

  • *.d.ts - TypeScript 声明文件
  • __tests__/** - 测试文件目录
  • *.test.{ts,tsx} - 测试文件
  • index.ts - 入口文件(通常只做导出)

设置覆盖率阈值

可以在 jest.config.ts 中启用覆盖率阈值,确保代码质量:

typescript 复制代码
coverageThreshold: {
  global: {
    branches: 80,    // 分支覆盖率至少 80%
    functions: 80,   // 函数覆盖率至少 80%
    lines: 80,       // 行覆盖率至少 80%
    statements: 80,  // 语句覆盖率至少 80%
  },
},

启用后,如果覆盖率低于阈值,测试将失败。

查看详细报告

HTML 报告

  1. 运行 pnpm test:coverage
  2. 打开 coverage/lcov-report/index.html
  3. 在浏览器中浏览:
    • 文件列表视图:查看每个文件的覆盖率
    • 文件详情视图:查看哪些行被覆盖,哪些未覆盖(红色=未覆盖,绿色=已覆盖)

终端输出示例

sql 复制代码
-------------------|---------|----------|---------|---------|
File               | % Stmts | % Branch | % Funcs | % Lines |
-------------------|---------|----------|---------|---------|
All files          |    XX   |    XX    |    XX   |    XX   |
 utils/            |    XX   |    XX    |    XX   |    XX   |
  file.ts          |    XX   |    XX    |    XX   |    XX   |
  guid.ts          |    XX   |    XX    |    XX   |    XX   |
-------------------|---------|----------|---------|---------|

其他有用的命令

bash 复制代码
# 只运行测试(不生成覆盖率)
pnpm test

# 监视模式运行测试
pnpm test:watch

# 只测试 uploader 包
pnpm test:uploader

# 生成覆盖率并只显示摘要(不生成 HTML)
jest --coverage --coverageReporters=text

覆盖率报告格式

Jest 默认生成以下格式的报告:

  • lcov - 用于 CI/CD 集成(coverage/lcov.info
  • text - 终端输出
  • text-summary - 终端摘要
  • html - HTML 报告(coverage/lcov-report/index.html

可以在 jest.config.ts 中自定义:

typescript 复制代码
coverageReporters: ['text', 'lcov', 'html', 'json-summary'],

CI/CD 集成

覆盖率报告可以集成到 CI/CD 流程中:

  1. GitHub Actions :使用 actions/upload-artifact 上传 coverage/ 目录
  2. Codecov :上传 coverage/lcov.info 到 Codecov
  3. Coveralls :上传 coverage/lcov.info 到 Coveralls

注意事项

  1. coverage 目录已添加到 .gitignore,不会提交到版本控制
  2. 覆盖率报告会显示所有源文件,包括未测试的文件
  3. 某些文件(如类型定义、入口文件)可能不需要 100% 覆盖率
  4. 覆盖率只是质量指标之一,不能完全代表代码质量

提高覆盖率

  1. 识别未覆盖的文件和函数
  2. 为关键业务逻辑编写测试
  3. 测试边界情况和错误处理
  4. 使用覆盖率报告找出遗漏的测试场景
相关推荐
hhcccchh4 小时前
1.2 CSS 基础选择器、盒模型、flex 布局、grid 布局
前端·css·css3
专吃海绵宝宝菠萝屋的派大星5 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
爱分享的阿Q5 小时前
Rust加WebAssembly前端性能革命实践指南
前端·rust·wasm
蓝黑20205 小时前
Vue的 value=“1“ 和 :value=“1“ 有什么区别
前端·javascript·vue
小李子呢02115 小时前
前端八股6---v-model双向绑定
前端·javascript·算法
He少年5 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
史迪仔01125 小时前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
AwesomeCPA5 小时前
Miaoduo MCP 使用指南(VDI内网环境)
前端·ui·ai编程
前端大波5 小时前
前端面试通关包(2026版,完整版)
前端·面试·职场和发展
qq_433502186 小时前
Codex cli 飞书文档创建进阶实用命令 + Skill 创建&使用 小白完整教程
java·前端·飞书