Nuxt 3项目中使用Playwright进行E2E测试如何获取代码覆盖率?
Nuxt 3 + Playwright E2E 代码覆盖率实现方案
答案是可以实现,以下是具体的配置步骤:
1. 安装依赖
首先安装所需的覆盖率相关包:
npm install -D vite-plugin-istanbul c8 @playwright/test
vite-plugin-istanbul:在Vite构建流程中注入代码覆盖率收集逻辑c8:轻量的覆盖率报告工具,基于Istanbul实现,无需复杂配置即可生成标准报告@playwright/test:Playwright核心测试框架
2. 配置Nuxt 3注入覆盖率代码
在nuxt.config.ts中添加Vite插件配置,确保仅在测试环境启用:
import { defineNuxtConfig } from 'nuxt/config' import istanbul from 'vite-plugin-istanbul' export default defineNuxtConfig({ vite: { plugins: [ // 仅在测试环境注入覆盖率代码 process.env.NODE_ENV === 'test' && istanbul({ include: ['src/**/*', 'components/**/*', 'pages/**/*'], // 根据你的项目目录结构调整 exclude: ['node_modules/**', '.nuxt/**', 'tests/**'], extension: ['.ts', '.vue'], requireEnv: false, // 强制启用,忽略环境变量自动检测 enableInDevMode: true // 在开发服务器模式下生效(Playwright测试通常连接开发服务器) }) ].filter(Boolean) } })
3. 配置Playwright收集覆盖率数据
我们通过Playwright的测试扩展钩子,在每个测试用例结束后收集覆盖率数据:
- 创建覆盖率钩子文件
tests/e2e/utils/coverage.ts:
import { test as base } from '@playwright/test' import fs from 'fs' import path from 'path' // 扩展Playwright测试上下文,添加覆盖率收集逻辑 export const test = base.extend({ context: async ({ context }, use) => { await use(context) // 在测试上下文销毁后,收集页面的覆盖率数据 const coverage = await context.evaluate(() => (window as any).__coverage__) if (coverage) { const coverageDir = path.join(process.cwd(), '.nyc_output') if (!fs.existsSync(coverageDir)) { fs.mkdirSync(coverageDir, { recursive: true }) } // 生成唯一文件名,避免多测试并行时覆盖数据 const filename = `coverage-${Date.now()}-${Math.random().toString(36).slice(2)}.json` fs.writeFileSync(path.join(coverageDir, filename), JSON.stringify(coverage)) } }, }) export { expect } from '@playwright/test'
- 在
playwright.config.ts中引入这个钩子,并配置测试环境:
import { defineConfig, devices } from '@playwright/test' export default defineConfig({ testDir: './tests/e2e', fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 1 : undefined, reporter: 'html', // 引入自定义测试钩子 setupFiles: ['./tests/e2e/utils/coverage.ts'], use: { baseURL: 'http://localhost:3000', // 指向Nuxt开发服务器地址 trace: 'on-first-retry', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, }, // 如需多浏览器测试,可添加firefox、webkit配置 ], // 自动启动Nuxt开发服务器(测试前无需手动启动) webServer: { command: 'npm run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, env: { NODE_ENV: 'test' // 设置测试环境,触发Nuxt的覆盖率插件 } }, })
如果需要单独查看每个测试用例的覆盖率报告,可以修改钩子逻辑,将每个测试的覆盖率数据保存到单独目录:
// 在coverage.ts的context钩子中,替换保存逻辑 export const test = base.extend({ context: async ({ context }, use, testInfo) => { await use(context) const coverage = await context.evaluate(() => (window as any).__coverage__) if (coverage) { // 以测试用例名称创建目录 const testCoverageDir = path.join( process.cwd(), '.nyc_output', testInfo.title.replace(/[^\w\-]/g, '-') ) if (!fs.existsSync(testCoverageDir)) { fs.mkdirSync(testCoverageDir, { recursive: true }) } fs.writeFileSync( path.join(testCoverageDir, 'coverage.json'), JSON.stringify(coverage) ) } }, })
4. 生成并查看覆盖率报告
在package.json中添加测试脚本:
{ "scripts": { "test:e2e": "playwright test", "test:e2e:coverage": "NODE_ENV=test playwright test && c8 report --reporter=html --reporter=lcov" } }
运行npm run test:e2e:coverage后,会在项目根目录的coverage文件夹生成HTML格式的覆盖率报告,直接打开coverage/index.html即可查看详细的覆盖率数据。
关键注意事项
- 测试必须连接Nuxt开发服务器:生产构建的代码经过压缩混淆,会导致覆盖率数据不准确甚至无法收集
- 静态站点(SSG)适配:如果项目使用静态生成,需要确保动态交互部分的代码能被覆盖率工具捕获,可能需要临时禁用部分预渲染逻辑
- 多浏览器并行测试:
c8会自动合并.nyc_output目录下的所有覆盖率文件,无需额外配置
内容的提问来源于stack exchange,提问作者Crackerjack
相关产品推荐
相关产品推荐

