vscode集成测试失败后不自动重试是默认行为,因vscode-test仅启动干净实例并交由jest/mocha执行测试,重试属测试框架策略且易掩盖flaky问题;jest 29+支持单用例.retry(n),ci中可对整个job重试但需人工核查失败根因。

VSCode集成测试失败后不自动重试,是默认行为,不是 bug —— vscode-test 本身不提供重试机制,必须手动封装逻辑或借助外部工具干预。
为什么 vscode-test 不支持原生重试
vscode-test 的核心是启动一个干净的 VSCode 实例、加载插件、执行测试入口(如 runTests()),它把测试执行完全交给你的测试框架(Jest/Mocha)。重试属于测试运行时策略,不在其职责范围内。
- 重试会掩盖 flaky 测试(如依赖时间、网络、UI 渲染顺序),官方倾向让你先定位并修复根本问题
- 多次启动 VSCode 实例开销大,CI 环境中易超时;本地调试时重复弹窗也影响体验
- 若测试本身已用
jest.retryTimes(2),但外层vscode-test启动失败(如扩展激活异常),重试仍不会触发
在 Jest 集成测试中启用单用例重试
如果你用 Jest 做集成测试(即测试代码跑在 vscode-test 启动的实例内),可在测试文件里对特定 it 或 test 加重试:
it('should insert snippet after delay', async () => {
await editor.insertSnippet(...);
await waitForEditorUpdate(); // 可能因渲染异步失败
}, 10000).retry(2); // Jest 29+ 支持 .retry(n)
- 仅对这个测试用例生效,不影响其他用例
- 需 Jest ≥ 29,且不能和
beforeEach中的异步 setup 混用(可能造成状态污染) - 失败时 Jest 会输出重试次数和每次的错误堆栈,方便比对差异
在 CI 中对整个集成测试流程加兜底重试
GitHub Actions 允许对 job 级别设置重试,适合应对环境级不稳定(如下载 VSCode 缓慢、端口占用、Xvfb 初始化失败):
jobs:
integration:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Run integration tests
run: npm run test:integration
# ⚠️ 注意:这里不是重试单个 test,而是整个 run 步骤
if: always()
continue-on-error: true
- name: Retry on failure
if: ${{ cancelled() || (failure() && steps.run-integration.outcome == 'failure') }}
run: npm run test:integration
- 该写法会完整重跑一次
npm run test:integration,包括重新下载 VSCode、解压、启动新实例 - 不要在
run行直接写npm run test:integration || npm run test:integration—— 这样失败日志会被吞掉,CI 无法标记为 failed - 建议配合
launchArgs: ['--disable-gpu', '--no-sandbox']减少 Linux CI 下的图形相关失败
避免重试掩盖真实问题的三个关键检查点
一旦你启用了任何形式的重试,以下三点必须人工确认,否则等于给坏测试发绿灯:
- 失败是否总发生在同一行?比如
await new Promise(setTimeout)里硬编码了 100ms,但 CI 机器 CPU 负载高导致超时 —— 应改用waitFor+ 条件判断,而非加 retry - 是否所有失败都带相同错误前缀?例如反复出现
Extension 'xxx' failed to activate,说明 activation 逻辑有竞态,应修复而非重试 - 重试后通过的用例,是否在第一次失败时留下了临时文件、未关闭的 WebSocket、或修改了全局状态?这些残留可能污染后续测试
重试不是容错方案,而是临时探针 —— 它只该用来帮你确认“这确实是环境抖动”,而不是替代对异步边界、资源清理和状态隔离的认真处理。











