Vitest与RTL测试钩子支持警告的解决方法问询
在基于Vite+TypeScript的React项目中,使用Vitest和RTL运行测试时出现以下钩子支持警告,虽测试能运行,但曾因未手动调用cleanup()导致测试异常:
stderr | unknown
test The current test runner does not support afterEach/teardown hooks. This means we won't be able to run automatic cleanup and you should be calling cleanup() manually.The current test runner does not support beforeAll/afterAll hooks. This means you should be setting IS_REACT_ACT_ENVIRONMENT manually.
项目环境:devContainer(Node.js & TypeScript镜像),Node版本20.x
项目依赖:
{ "name": "armada-website", "private": true, "version": "1.0.0", "engines": { "node": "20.x" }, "scripts": { "dev": "vite", "test": "vitest", "coverage": "vitest --coverage", }, "dependencies": { "@swc/helpers": "^0.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0" }, "devDependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react-swc": "^3.2.0", "@vitest/coverage-istanbul": "^0.29.8", "happy-dom": "^12.10.3", "jsdom": "^21.1.1", "typescript": "^5.2.2", "vite": "^4.5.0", "vite-tsconfig-paths": "^4.2.1", "vitest": "^0.29.7" }, }
Vite配置(vite.config.ts):
import react from '@vitejs/plugin-react-swc'; import type { UserConfig } from 'vite'; import { defineConfig } from 'vite'; import tsconfigPaths from 'vite-tsconfig-paths'; import type { InlineConfig } from 'vitest'; interface VitestConfigExport extends UserConfig { test: InlineConfig; } // https://vitejs.dev/config/ export default defineConfig({ plugins: [react(), tsconfigPaths()], test: { environment: 'happy-dom', coverage: { provider: 'istanbul', lines: 90, functions: 90, branches: 90, statements: 90, }, dir: 'src/__tests__', }, exclude: ['src/__tests__'], } as VitestConfigExport);
TypeScript配置(tsconfig.json):
{ "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "noEmit": true, "jsx": "preserve", "incremental": true, "baseUrl": ".", "paths": { "~/*": ["src/*"] } }, "include": ["vite.config.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] }
此前相同配置版本的项目无此警告,需解决警告保障测试环境稳定。
1. 开启Vitest全局测试钩子
RTL v14+依赖测试框架的全局钩子(afterEach/beforeAll等)来自动执行cleanup和设置IS_REACT_ACT_ENVIRONMENT,需在Vitest配置中开启全局变量支持:
修改vite.config.ts的test配置,添加globals: true:
test: { environment: 'happy-dom', globals: true, // 新增:开启全局测试钩子 coverage: { provider: 'istanbul', lines: 90, functions: 90, branches: 90, statements: 90, }, dir: 'src/__tests__', },
2. 创建测试全局初始化文件
在src/__tests__目录下创建setup.ts,统一配置RTL的自动cleanup、jest-dom扩展及IS_REACT_ACT_ENVIRONMENT:
// src/__tests__/setup.ts import '@testing-library/jest-dom'; import { cleanup } from '@testing-library/react'; // 自动在每个测试后执行cleanup afterEach(() => { cleanup(); }); // 手动设置IS_REACT_ACT_ENVIRONMENT,确保React的act机制正常工作 globalThis.IS_REACT_ACT_ENVIRONMENT = true;
然后在vite.config.ts的test配置中引入这个文件:
test: { environment: 'happy-dom', globals: true, setupFiles: ['./src/__tests__/setup.ts'], // 新增:导入全局初始化文件 coverage: { provider: 'istanbul', lines: 90, functions: 90, branches: 90, statements: 90, }, dir: 'src/__tests__', },
3. 修正Vite配置中的错误
原配置中顶层的exclude: ['src/__tests__']会导致Vitest无法找到测试文件(因为dir已经指定了测试目录),需移除顶层的exclude,如果需要排除特定文件,应将exclude放在test配置内:
export default defineConfig({ plugins: [react(), tsconfigPaths()], test: { environment: 'happy-dom', globals: true, setupFiles: ['./src/__tests__/setup.ts'], coverage: { provider: 'istanbul', lines: 90, functions: 90, branches: 90, statements: 90, }, dir: 'src/__tests__', // 如果需要排除测试目录内的特定文件,在这里添加 // exclude: ['src/__tests__/some-ignore-file.ts'], }, // 移除顶层的exclude } as VitestConfigExport);
4. 对齐Vitest相关依赖版本
当前项目中vitest版本为0.29.7,而@vitest/coverage-istanbul为0.29.8,版本不一致可能导致兼容性问题,需修改package.json将两者版本统一:
{ "devDependencies": { // ... "@vitest/coverage-istanbul": "^0.29.7", "vitest": "^0.29.7" // ... } }
修改后执行npm install或pnpm install更新依赖。
内容的提问来源于stack exchange,提问作者Mohamed Ali Ben Thaier

