# 测试插件
VS Code 为你的插件提供了运行和调试的能力。测试会运行在一个特殊的 VS Code 实例中——扩展开发环境
,这个特殊实例拥有访问 VS Code API 的全部权限。本篇侧重于 VS Code 的集成测试,至于单元测试,你可以使用任何流行的测试框架,如Mocha或者Jasmine。
# 概述
如果你原本使用vscode
库进行测试,可以参考从vscode
迁移部分
如果你正在使用yo code 生成器,那么生成的项目中应该已经包含了一些测试示例和指引。
使用npm run test
或者yarn test
启动集成测试,测试工程随后会:
- 下载并解压最新的 VS Code 版本
- 运行插件的测试脚本中所规定的Mocha测试
你可以在helloworld-test-sample中找到本篇示例,本篇剩余部分将解释例子中的如下部分:
- 测试入口(src/test/runTest.ts)
- 测试脚本(src/test/suite/index.ts)
# 测试入口
VS Code 提供了 2 个 CLI 参数来运行插件测试——--extensionDevelopmentPath
和--extensionTestsPath
。
例如:
# - Launches VS Code Extension Host # - Loads the extension at <EXTENSION-ROOT-PATH> # - Executes the test runner script at <TEST-RUNNER-SCRIPT-PATH> code \ --extensionDevelopmentPath=<EXTENSION-ROOT-PATH> \ --extensionTestsPath=<TEST-RUNNER-SCRIPT-PATH>
代码已复制
2
3
4
5
6
测试入口(src/test/runTest.ts))使用了vscode-test
API,简化了下载、解压、启动 VS Code 的测试流程:
import * as path from "path"; import { runTests } from "vscode-test"; async function main() { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` const extensionDevelopmentPath = path.resolve(__dirname, "../../"); // The path to the extension test runner script // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, "./suite/index"); // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, extensionTestsPath }); } catch (err) { console.error("Failed to run tests"); process.exit(1); } } main();
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vscode-test
还支持:
- 启动 VS Code 时打开指定工作区
- 下载不同版本的 VS Code
- 使用其他 CLI 参数启动
你可以在microsoft/vscode-test中找到更多用法。
# 测试脚本
当你运行插件的集成测试时,--extensionTestsPath
会指向测试脚本(src/test/suite/index.ts),然后这个脚本会进一步运行测试套件。下面是helloworld-test-sample
中的测试脚本,它使用了 Mocha 运行测试套件。你可以把这个文件视为测试的起点,你可以用Mocha 的 API自定义启动时的配置,你也可以用其他任意喜欢的测试框架替代 Mocha。
import * as path from "path"; import * as Mocha from "mocha"; import * as glob from "glob"; export function run(): Promise<void> { // Create the mocha test const mocha = new Mocha({ ui: "tdd" }); mocha.useColors(true); const testsRoot = path.resolve(__dirname, ".."); return new Promise((c, e) => { glob("**/**.test.js", { cwd: testsRoot }, (err, files) => { if (err) { return e(err); } // Add files to the test suite files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); try { // Run the mocha test mocha.run(failures => { if (failures > 0) { e(new Error(`${failures} tests failed.`)); } else { c(); } }); } catch (err) { e(err); } }); }); }
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
所有测试脚本和*.test.js
文件都有访问 VS Code API 的权限。
看看这个例子(src/test/suite/extension.test.ts)
import * as assert from "assert"; import { after } from "mocha"; // You can import and use all API from the 'vscode' module // as well as import your extension to test it import * as vscode from "vscode"; // import * as myExtension from '../extension'; suite("Extension Test Suite", () => { after(() => { vscode.window.showInformationMessage("All tests done!"); }); test("Sample test", () => { assert.equal(-1, [1, 2, 3].indexOf(5)); assert.equal(-1, [1, 2, 3].indexOf(0)); }); });
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 调试测试文件
调试测试文件和调试插件是一样的,我们看一个launch.json
调试器配置的例子:
{ "version": "0.2.0", "configurations": [ { "name": "Extension Tests", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" ], "outFiles": ["${workspaceFolder}/out/test/**/*.js"] } ] }
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 提示
# 使用 Insider 版本开发插件
由于 VS Code 的限制,如果你使用 VS Code 稳定版来运行集成测试,它会报错:
Running extension tests from the command line is currently only supported if no other instance of Code is running.
代码已复制
所以推荐你使用VS Code Insiders测试插件。
# 调试时禁用其他插件
当你在 VS Code 中对测试进行调试时,VS Code 使用的是全局安装的 VS Code 实例,它会加载所有插件。你可以在launch.json
中添加--disable-extensions
或者在runTests
的launchArgs
选项中添加该项以禁用其他插件。
{ "version": "0.2.0", "configurations": [ { "name": "Extension Tests", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--disable-extensions", "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" ], "outFiles": ["${workspaceFolder}/out/test/**/*.js"] } ] }
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
await runTests({ extensionDevelopmentPath, extensionTestsPath, /** * A list of launch arguments passed to VS Code executable, in addition to `--extensionDevelopmentPath` * and `--extensionTestsPath` which are provided by `extensionDevelopmentPath` and `extensionTestsPath` * options. * * If the first argument is a path to a file/folder/workspace, the launched VS Code instance * will open it. * * See `code --help` for possible arguments. */ launchArgs: ["--disable-extensions"] });
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用vscode-test
自定义配置
你可能会需要自定义一些启动配置,比如启动测试前执行code --install-extension
安装一些其他插件这样的场景。vscode-test
提供粒度更细的 API 来操作这样的场景:
const cp = require("child_process"); const { downloadAndUnzipVSCode, resolveCliPathFromExecutablePath } = require("vscode-test"); const vscodeExecutablePath = await downloadAndUnzipVSCode("1.34.0"); const cliPath = resolveCliPathFromExecutablePath(vscodeExecutablePath); // Use cp.spawn / cp.exec for custom setup cp.spawnSync( cliPath, ["--install-extension", "<EXTENSION-ID-OR-PATH-TO-VSIX>"], { encoding: "utf-8", stdio: "inherit" } ); // Run the extension test await runTests({ // Use the specified `code` executable vscodeExecutablePath, extensionPath, testRunnerPath });
代码已复制
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 从 vscode 迁移
vscode
中的集成测试模块已迁移到vscode-test
,你可以按下面的步骤进行迁移:
移除
vscode
依赖添加
vscode-test
依赖由于旧的
vscode
模块会下载 VS Code 类型定义,所以你需要- 手动安装
@types/vscode
,这个版本需和你package.json
的engine.vscode
版本一致,比如你的engine.vscode
版本是1.30
,那么就安装@types/vscode@1.30
- 删除
package.json
中的"postinstall": "node ./node_modules/vscode/bin/install"
- 手动安装
添加一个测试入口,你可以像我们的示例一样,用
runTest.ts
作为入口。指定
package.json
中的test
脚本,运行编译后的runTest.ts
。添加一个测试脚本,你可以用sample test runner script作为入口。注意
vscode
过去依赖mocha@4
和glob
,现在你需要自己安装到devDependency
里去。
# 下一步
- 持续集成:将你的插件运行在持续集成服务中,比如 Azure Devops。