ViTest多模块分文件测试失败问题求助
解决方案
针对你遇到的Vitest多测试文件运行失败的问题,核心原因是测试文件并行执行时重复创建数据库连接,导致连接冲突或数据清理时机不对,可以通过以下几个方案解决:
1. 串行执行测试文件
Vitest默认并行运行测试文件,每个文件是独立进程,会重复初始化数据库连接,容易引发端口占用、连接池耗尽等问题。可以在配置文件中强制串行执行:
在vitest.config.ts中添加:
export default defineConfig({ test: { sequential: true, // 所有测试文件串行执行 // 或者限制并发数,比如只允许1个工作进程 // maxWorkers: 1, }, })
2. 复用单例数据库连接
不要让每个测试文件单独创建数据库连接,改用单例模式确保整个测试生命周期只初始化一次连接:
创建src/db/test-connection.ts:
import { PrismaClient } from '@prisma/client' // 以Prisma为例,替换成你的数据库客户端 let dbClient: PrismaClient // 利用全局变量复用连接,避免每个测试文件重新实例化 if (process.env.NODE_ENV === 'test') { if (!global.dbClient) { global.dbClient = new PrismaClient({ // 测试环境专属配置 datasources: { db: { url: process.env.DATABASE_URL_TEST }, }, }) } dbClient = global.dbClient } else { dbClient = new PrismaClient() } export default dbClient
所有测试文件都导入这个单例连接,避免重复创建数据库连接。
3. 优化数据清理策略,用事务回滚替代全量清理
每次测试前全量清理数据库不仅效率低,还可能在并行执行时出现数据竞争。改用事务包裹测试,每个测试结束后回滚事务,既保证数据隔离,又避免重复清理:
在Vitest的全局setup文件(比如vitest.setup.ts)中配置:
import dbClient from './src/db/test-connection' // 所有测试开始前只连接一次数据库 beforeAll(async () => { await dbClient.$connect() }) // 每个测试前开启事务 beforeEach(async () => { await dbClient.$executeRawUnsafe('BEGIN') }) // 每个测试结束后回滚事务,恢复初始状态 afterEach(async () => { await dbClient.$executeRawUnsafe('ROLLBACK') }) // 所有测试结束后断开连接 afterAll(async () => { await dbClient.$disconnect() })
记得在vitest.config.ts中指定setup文件:
export default defineConfig({ test: { setupFiles: ['./vitest.setup.ts'], }, })
4. 确保测试环境使用独立数据库
务必为测试环境配置单独的数据库(比如myapp_test),避免测试数据污染开发/生产环境,同时也能避免不同测试进程之间的数据库操作冲突。
内容的提问来源于stack exchange,提问作者Mr.Singh
相关产品推荐
相关产品推荐

