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

Vitest与RTL测试钩子支持警告的解决方法问询

问题:Vitest + React Testing Library 钩子支持警告及测试稳定性问题

在基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:44:59