前端项目测试覆盖率检测

背景介绍

什么是测试覆盖率?

测试覆盖率(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. 使用覆盖率报告找出遗漏的测试场景
相关推荐
pas1364 小时前
29-mini-vue element搭建更新
前端·javascript·vue.js
IT=>小脑虎4 小时前
2026版 React 零基础小白进阶知识点【衔接基础·企业级实战】
前端·react.js·前端框架
IT=>小脑虎4 小时前
2026版 React 零基础小白入门知识点【基础完整版】
前端·react.js·前端框架
FinClip4 小时前
微信AI小程序“亿元计划”来了!你的APP如何一键接入,抢先变现?
前端·微信小程序·app
西西学代码4 小时前
Flutter---框架
前端·flutter
XiaoYu20025 小时前
第9章 Three.js载入模型GLTF
前端·javascript·three.js
.又是新的一天.5 小时前
【前端Web开发HTML5+CSS3+移动web视频教程】01 html- 标签之文字排版、图片、链接、音视频
前端·css3·html5
神奇的程序员5 小时前
开发了一个nginx日志分析面板
前端
阿拉丁的梦5 小时前
【C4D实用脚本】清除废点及删除了面的选择tag和材质tag及材质--AI编程
服务器·前端·材质
傅里叶5 小时前
Flutter移动端获取相机内参
前端·flutter