Jest+SuperTest本地测试通过但GitHub Actions中无法退出
GitHub Actions中Jest测试无限运行无法退出的排查方案
一、先核对GitHub Actions配置(node.yml)
- 对齐Node.js版本:本地测试正常但CI出问题,首先要确保Actions里的Node版本和本地完全一致。默认的Node版本可能和你本地使用的有差异,直接在配置里指定版本:
steps: - uses: actions/checkout@v4 - name: 配置Node.js环境 uses: actions/setup-node@v4 with: node-version: '18.x' # 替换成你本地用的版本 cache: 'npm' - 统一测试命令参数:Jest在CI环境下并行测试可能触发资源冲突,导致进程挂起。试试在测试命令里加
--runInBand强制串行执行,同时确保和本地执行的命令完全一致:- name: 运行测试 run: npm test -- --runInBand - 用
npm ci安装依赖:避免依赖版本不一致的问题,Actions里优先用npm ci替代npm install,它会严格按照package-lock.json安装依赖:- name: 安装依赖 run: npm ci
二、检查测试代码中的资源泄漏
- 确保Express服务器正确关闭:如果测试中手动启动了服务器,务必在测试结束后关闭。不要依赖SuperTest自动处理,显式关闭更可靠:
let server; beforeAll(() => { // 用0让系统分配随机端口,避免端口占用 server = app.listen(0); }); afterAll(async () => { // 等待服务器完全关闭 await new Promise(resolve => server.close(resolve)); }); - 关闭外部服务连接:如果测试用到了数据库、Redis等外部服务,测试结束后必须断开连接。比如Mongoose的场景:
afterAll(async () => { await mongoose.disconnect(); }); - 排查未完成的异步操作:测试中的
setTimeout、setInterval或者未resolve的Promise会让Jest一直等待。可以用jest.useFakeTimers()模拟定时器,或者确保所有异步逻辑都在测试结束前完成。 - 临时用
--forceExit验证:如果不确定是哪个资源没释放,可以先在测试命令里加--forceExit,如果能正常退出,说明确实存在未释放的资源,再针对性排查:- name: 运行测试 run: npm test -- --forceExit
三、进阶排查技巧
- 打印环境和配置信息:在Actions步骤里添加日志,对比本地和CI的环境差异:
- name: 打印环境信息 run: | echo "Node版本: $(node -v)" echo "NPM版本: $(npm -v)" npx jest --showConfig # 打印Jest配置 - 逐步缩小测试范围:先注释掉大部分测试用例,只保留一个最简单的接口测试,看看能否正常退出。如果可以,再逐个恢复测试,定位到导致问题的具体用例。
内容的提问来源于stack exchange,提问作者Awais Aslam
相关产品推荐
相关产品推荐

