You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Next.js应用中使用Istanbul实现代码覆盖率遇阻求助

Next.js + Cypress 代码覆盖率配置失败解决方案

问题描述

我用Cypress给Next.js应用写了前端测试,现在要加代码覆盖率检测来追踪未测试模块,但按照官方指南用istanbuljs实现时一直失败。试过用nyc把代码插桩到/instrumented目录运行,也试过集成到Babel流水线,结果要么测试正常跑但没覆盖率数据,要么应用直接启动不了。如果项目里有.babelrc文件,每个页面/组件都会抛出'React is undefined'错误。

当前依赖配置:

"devDependencies": {
    "@babel/preset-react": "^7.18.6",
    "@cypress/code-coverage": "^3.10.0",
    "babel-plugin-istanbul": "^6.1.1",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "cypress": "^10.1.0",
    "cypress-react-selector": "^2.3.20",
    "nyc": "^15.1.0"
}

之前的错误配置:

  • .babelrc(存在则应用崩溃):
{
    "presets": ["@babel/preset-react"],
    "plugins": ["transform-class-properties", "istanbul"]
}
  • support/e2e.js:
import './commands';
import '@cypress/code-coverage/support';
  • cypress.config.js:
const { defineConfig } = require('cypress');

module.exports = defineConfig({
    e2e: {
        baseUrl: 'http://localhost:3000',
        setupNodeEvents(on, config) {
            require('@cypress/code-coverage/task')(on, config);
            on('file:preprocessor', require('@cypress/code-coverage/use-babelrc'));
            return config;
        },
    },
    watchForFileChanges: false,
    defaultCommandTimeout: 1000000,
});

解决方案

1. 删除根目录的.babelrc文件

Next.js默认使用next/babel预设,这个预设包含了自动引入React的功能(无需手动写import React from 'react')。自定义.babelrc会覆盖Next.js的默认预设,导致React未被自动引入,出现'React is undefined'错误。

2. 在next.config.js中配置Babel插桩

把istanbul插件集成到Next.js的webpack配置里,仅在测试环境启用:

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (config, { dev, isServer }) => {
    // 仅在测试环境添加istanbul插桩
    if (process.env.NODE_ENV === 'test') {
      config.module.rules.push({
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['next/babel'], // 复用Next.js默认Babel预设
            plugins: ['babel-plugin-istanbul', 'transform-class-properties'],
          },
        },
      });
    }
    return config;
  },
};

module.exports = nextConfig;

3. 调整Cypress配置文件

替换原有的file:preprocessor配置,改用Next.js的webpack配置作为预处理器,同时可以启用Cypress的devServer自动启动Next服务:

const { defineConfig } = require('cypress');
const { startDevServer } = require('@cypress/webpack-dev-server');
const nextConfig = require('./next.config.js');

module.exports = defineConfig({
  e2e: {
    // 注释baseUrl,改用devServer自动启动服务
    // baseUrl: 'http://localhost:3000',
    setupNodeEvents(on, config) {
      // 注册代码覆盖率任务
      require('@cypress/code-coverage/task')(on, config);
      return config;
    },
    // 配置devServer自动启动Next应用
    devServer: {
      framework: 'next',
      bundler: 'webpack',
      webpackConfig: nextConfig,
    },
  },
  watchForFileChanges: false,
  defaultCommandTimeout: 1000000,
});

4. 添加NYC配置(可选)

在项目根目录创建.nycrc文件,自定义覆盖率报告格式和范围:

{
  "include": ["src/**/*.{js,jsx,ts,tsx}"],
  "exclude": ["node_modules", ".next", "cypress", "public"],
  "reporter": ["html", "text-summary"],
  "all": true
}

5. 运行测试命令

在package.json中添加测试脚本,确保设置测试环境变量:

"scripts": {
  "test:e2e": "NODE_ENV=test cypress run",
  "test:e2e:open": "NODE_ENV=test cypress open"
}

执行命令:

npm run test:e2e

测试完成后,会在项目根目录生成coverage文件夹,打开其中的index.html即可查看详细的代码覆盖率报告。


内容的提问来源于stack exchange,提问作者alon rubin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:50:44