VSCode扩展测试必须用vscode-test启动真实实例,因type:"extensionHost"才能触发插件生命周期和vscode API;testRunner.js是强制入口,需导出run函数;断点失效常因版本不匹配、outFiles缺失或ESM导入错误。

VSCode 扩展测试不能靠“装完插件就跑”,必须用 vscode-test 启动真实 VSCode 实例,否则所有 UI 交互、命令注册、状态管理类逻辑全不可测——你写的 test() 函数可能根本没被调用。
为什么 launch.json 里 type 是 extensionHost 而不是 node
VSCode 扩展运行在两个隔离进程:Extension Host(负责执行你的 activate() 和命令逻辑)和 Renderer(Webview、UI 渲染)。测试必须走 Extension Host 流程,才能触发 vscode.commands.registerCommand、vscode.window.showInformationMessage 等真实 API。
-
type: "node"会直接执行 JS 文件,绕过整个 VSCode 插件生命周期,vscode全局对象是空的,Cannot read property 'commands' of undefined必报 -
type: "extensionHost"让 VSCode 启动一个干净的开发版实例,加载你的扩展,并把--extensionTestsPath指向的测试入口文件注入进去 - 别漏掉
"runtimeExecutable": "${execPath}"—— 这告诉 VSCode 用当前编辑器二进制启动新实例,不是用系统 Node.js
testRunner.js 是什么,能删吗
它不是可选胶水文件,而是 vscode-test 的强制入口契约。VSCode 测试 runner 不认 .ts 或 index.test.ts,只认一个导出 run() 函数的 JS 文件。
- 必须存在且路径与
launch.json中"--extensionTestsPath"一致(如${workspaceFolder}/out/test/testRunner.js) - 内容极简,但不可省:
const path = require('path');<br>const Mocha = require('mocha');<br>const glob = require('glob');<br><br>async function run() {<br> const mocha = new Mocha({ ui: 'tdd' });<br> const testsPath = path.resolve(__dirname, '..', '..', 'test', '**', '*.test.js');<br> glob.sync(testsPath).forEach(file => mocha.addFile(file));<br> try {<br> await new Promise((resolve, reject) => {<br> mocha.run(failures => (failures ? reject(new Error(`${failures} failures`)) : resolve()));<br> });<br> } catch (err) {<br> console.error(err);<br> throw err;<br> }<br>}<br><br>module.exports = { run }; - 如果用 TypeScript 写测试,必须先
tsc -p ./test/tsconfig.json编译到out/test/,再让testRunner.js加载 JS
断点不命中?检查三个硬性依赖
VSCode 调试扩展测试时,断点失效不是配置问题,而是环境链断裂。以下任一缺失都会导致调试器连不上或跳过代码:
-
vscode-test版本必须匹配你本地 VSCode 的版本(比如你用的是 1.89.x,就得装vscode-test@^1.89.0),否则activate()根本不会被调用 -
out/test/testRunner.js必须在launch.json的"outFiles"列表里,否则调试器找不到映射源码的 map 文件,断点打在 JS 上无效 - 测试文件里不能用
import * as assert from 'assert'——vscode-test运行时是 CommonJS 环境,ESM 会报ERR_REQUIRE_ESM;改用const assert = require('assert');
CI 里跑不通?关键在 DISPLAY 和 --no-sandbox
GitHub Actions 或 GitLab CI 默认无图形界面,但 vscode-test 启动 VSCode 实例需要 GUI 支持。本地能跑不代表 CI 能过。
- Linux CI 必须加
export DISPLAY=:99并启动xvfb-run,否则卡在启动界面 - 加
--no-sandbox参数(写在args里),否则 Chromium 渲染进程因权限被杀,日志停在Starting VS Code... - 不要用
npm test直接调vscode-test—— 它不处理这些环境适配,必须用vscode-test自带的 CLI 封装,例如:npx @vscode/test-electron --extensionDevelopmentPath=. --extensionTestsPath=./out/test
最常被忽略的是:测试代码里调用 vscode.window.showQuickPick 或 vscode.workspace.openTextDocument 时,不 mock 返回值就必然失败——这些 API 在 headless 环境下要么返回 undefined,要么抛错。你得在每个 test suite 开头用 jest.mock('vscode') 显式控制它们的行为。


















