如何配置Jest以获取Selenium测试的代码覆盖率?
问题描述
刚在JavaScript项目中切换到Jest进行测试,之前用Mocha+Chai时无法获取基于Babel和Selenium的组件测试覆盖率,转用Jest后单元测试能正常生成覆盖率,但Selenium测试几乎无法贡献覆盖率(禁用单元测试后覆盖率接近0)。使用的Jest版本是29.3.1,相关配置和依赖如下:
jest.config.js
{ collectCoverage: true, coverageDirectory: 'coverage', coverageProvider: 'babel', coverageReporters: [ 'html' ] }
依赖项(package.json)
"dependencies": { "@babel/cli": "^7.19.3", "@babel/core": "^7.20.2", "@babel/preset-env": "^7.20.2", "@babel/register": "^7.18.9", "babel-jest": "^29.3.1", "babel-plugin-rewire": "^1.2.0", "chai": "^4.3.6", "eslint": "^8.9.0", "eslint-plugin-html": "^6.2.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-mocha": "^10.1.0", "express": "^4.18.2", "jest": "^29.3.1", "mocha": "^10.1.0", "rewire": "^6.0.0", "selenium-webdriver": "^4.6.0", "sinon": "^14.0.1" }
解决方案
Selenium属于端到端测试,代码运行在浏览器环境中,Jest默认的Babel覆盖率收集仅针对Node环境执行的代码(如单元测试),因此需要额外配置来捕获浏览器中的代码执行情况:
- 安装
babel-plugin-istanbul
该插件会在Babel编译时向源码注入覆盖率收集代码,支持浏览器环境:
npm install --save-dev babel-plugin-istanbul
- 配置Babel启用覆盖率注入
创建或修改babel.config.js,在测试环境下启用istanbul插件:
module.exports = { presets: ['@babel/preset-env'], plugins: ['babel-plugin-rewire'], env: { test: { plugins: ['istanbul'] } } };
- 在Selenium测试中提取浏览器覆盖率数据
测试结束后,从浏览器的window.__coverage__对象中提取覆盖率数据并写入文件(供后续合并):
const fs = require('fs'); const path = require('path'); // 提取并保存覆盖率数据的工具函数 async function saveSeleniumCoverage(driver) { try { const coverage = await driver.executeScript('return window.__coverage__;'); if (!coverage) return; // 创建临时目录存储覆盖率文件 const outputDir = path.resolve(__dirname, '.nyc_output'); if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir); // 写入唯一命名的覆盖率文件 const filePath = path.join(outputDir, `selenium-coverage-${Date.now()}.json`); fs.writeFileSync(filePath, JSON.stringify(coverage)); } catch (err) { console.error('提取Selenium覆盖率失败:', err); } } // 在测试结束后调用(示例) afterAll(async () => { await saveSeleniumCoverage(driver); await driver.quit(); });
- 合并并生成完整覆盖率报告
使用nyc(Istanbul的CLI工具)合并单元测试和Selenium测试的覆盖率数据,生成统一报告:
- 安装
nyc:
npm install --save-dev nyc
- 修改
package.json中的测试脚本:
{ "scripts": { "test": "jest", "coverage": "jest && nyc report --reporter=html --report-dir=coverage" } }
- 运行
npm run coverage即可生成包含Selenium测试的完整覆盖率报告。
- 补充Jest配置确保覆盖范围正确
在jest.config.js中添加collectCoverageFrom和testMatch,明确需要收集覆盖率的文件路径和测试文件范围:
{ collectCoverage: true, coverageDirectory: 'coverage', coverageProvider: 'babel', coverageReporters: [ 'html' ], collectCoverageFrom: [ 'src/**/*.js', // 替换为你的源码目录 '!node_modules/**', '!**/*.test.js' ], testMatch: [ '**/__tests__/**/*.js', '**/?(*.)+(spec|test).js', '**/selenium-tests/**/*.js' // 替换为你的Selenium测试目录 ] }
注意:确保Selenium加载的是测试环境下编译的代码(包含覆盖率注入逻辑),而非生产环境的压缩/混淆代码。
内容的提问来源于stack exchange,提问作者Graeme Perrow
相关产品推荐
相关产品推荐

