vitest.config.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import path from "node:path";
  2. import { defineConfig } from "vitest/config";
  3. export default defineConfig({
  4. test: {
  5. // ==================== 全局配置 ====================
  6. globals: true, // 使用全局 API (describe, test, expect)
  7. projects: [
  8. {
  9. extends: true,
  10. test: {
  11. environment: "happy-dom",
  12. include: [
  13. "tests/unit/**/*.{test,spec}.tsx",
  14. "tests/api/**/*.{test,spec}.tsx",
  15. "src/**/*.{test,spec}.tsx",
  16. ],
  17. },
  18. },
  19. ],
  20. // 测试前置脚本
  21. setupFiles: ["./tests/setup.ts"],
  22. // UI 配置
  23. // Vitest UI/Server 使用的是 test.api(不是 Vite 的 server 配置)
  24. // 默认仅允许本机访问,避免浏览器尝试连接 0.0.0.0 导致 UI 显示 Disconnected
  25. api: {
  26. host: process.env.VITEST_API_HOST || "127.0.0.1",
  27. port: Number(process.env.VITEST_API_PORT || 51204),
  28. strictPort: false,
  29. },
  30. open: false, // 不自动打开浏览器(手动访问 http://localhost:51204/__vitest__/)
  31. // ==================== 覆盖率配置 ====================
  32. coverage: {
  33. provider: "v8",
  34. reporter: ["text", "html", "lcov", "json"],
  35. reportsDirectory: "./coverage",
  36. // 排除文件
  37. exclude: [
  38. "node_modules/",
  39. "tests/",
  40. "*.config.*",
  41. "**/*.d.ts",
  42. ".next/",
  43. "dist/",
  44. "build/",
  45. // 单元测试覆盖率仅统计「可纯函数化/可隔离」模块,避免把需要 DB/Redis/Next/Bull 的集成逻辑算进阈值
  46. "src/actions/**",
  47. "src/repository/**",
  48. "src/app/v1/_lib/**",
  49. "src/lib/provider-testing/**",
  50. "src/lib/notification/**",
  51. "src/lib/redis/**",
  52. "src/lib/utils/**",
  53. "src/lib/rate-limit/**",
  54. "src/components/quota/**",
  55. // 依赖外部系统或目前无单测覆盖的重模块(避免拉低全局阈值)
  56. "src/lib/session-manager.ts",
  57. "src/lib/session-tracker.ts",
  58. "src/lib/circuit-breaker.ts",
  59. "src/lib/error-override-validator.ts",
  60. "src/lib/error-rule-detector.ts",
  61. "src/lib/sensitive-word-detector.ts",
  62. "src/lib/price-sync.ts",
  63. "src/lib/proxy-status-tracker.ts",
  64. "src/hooks/useCountdown.ts",
  65. ],
  66. // 覆盖率阈值(可选)
  67. thresholds: {
  68. lines: 50,
  69. functions: 50,
  70. branches: 40,
  71. statements: 50,
  72. },
  73. },
  74. // ==================== 超时配置 ====================
  75. testTimeout: 10000, // 单个测试超时 10 秒
  76. hookTimeout: 10000, // 钩子函数超时 10 秒
  77. // ==================== 并发配置 ====================
  78. maxConcurrency: 5, // 最大并发测试数
  79. pool: "threads", // 使用线程池(推荐)
  80. // ==================== 文件匹配 ====================
  81. include: [
  82. "tests/unit/**/*.{test,spec}.ts", // 单元测试
  83. "tests/api/**/*.{test,spec}.ts", // API 测试
  84. "src/**/*.{test,spec}.ts", // 支持源码中的测试
  85. ],
  86. exclude: [
  87. "node_modules",
  88. ".next",
  89. "dist",
  90. "build",
  91. "coverage",
  92. "**/*.d.ts",
  93. // 排除需要 Next.js 完整运行时的集成测试
  94. "tests/integration/**",
  95. "tests/api/users-actions.test.ts",
  96. "tests/api/providers-actions.test.ts",
  97. "tests/api/keys-actions.test.ts",
  98. "tests/api/my-usage-readonly.test.ts",
  99. ],
  100. // ==================== 监听模式配置 ====================
  101. // 不在配置文件中强制 watch=false,否则 vitest --ui 可能会在执行完一次后退出,UI 显示 Disconnected
  102. // 通过命令行参数控制:vitest(watch)/ vitest run(单次运行)
  103. // ==================== 报告器配置 ====================
  104. reporters: ["verbose"], // 详细输出
  105. // ==================== 隔离配置 ====================
  106. isolate: true, // 每个测试文件在独立环境中运行
  107. // ==================== Mock 配置 ====================
  108. mockReset: true, // 每个测试后重置 mock
  109. restoreMocks: true, // 每个测试后恢复原始实现
  110. clearMocks: true, // 每个测试后清除 mock 调用记录
  111. // ==================== 快照配置 ====================
  112. resolveSnapshotPath: (testPath, snapExtension) => {
  113. return testPath.replace(/\.test\.([tj]sx?)$/, `${snapExtension}.$1`);
  114. },
  115. },
  116. // ==================== 路径别名(与 tsconfig.json 保持一致)====================
  117. resolve: {
  118. alias: {
  119. "@": path.resolve(__dirname, "./src"),
  120. "@messages": path.resolve(__dirname, "./messages"),
  121. // Mock server-only 包,避免测试环境报错
  122. "server-only": path.resolve(__dirname, "./tests/server-only.mock.ts"),
  123. },
  124. },
  125. });