測試擴充功能
Visual Studio Code 支援為您的擴充功能執行和偵錯測試。這些測試將在 VS Code 的特殊執行個體(名為 擴充功能開發主機)內執行,並可完整存取 VS Code API。我們將這些測試稱為整合測試,因為它們超越了可以在沒有 VS Code 執行個體的情況下執行的單元測試。本文件著重於 VS Code 整合測試。
概觀
如果您使用 Yeoman Generator 來建立擴充功能骨架,則已為您建立整合測試。
在產生的擴充功能中,您可以使用 npm run test
或 yarn test
來執行整合測試,這些測試會
- 下載並解壓縮最新版本的 VS Code。
- 執行擴充功能測試執行器腳本指定的 Mocha 測試。
快速設定:測試 CLI
VS Code 團隊發佈了一個命令列工具來執行擴充功能測試。您可以在 擴充功能範例存放庫中找到範例。
測試 CLI 提供快速設定,也讓您可以使用 Extension Test Runner 輕鬆執行和偵錯 VS Code UI 的測試。CLI 獨家使用底層的 Mocha。
若要開始使用,您會想要先安裝 @vscode/test-cli
模組,以及讓測試能在 VS Code Desktop 中執行的 @vscode/test-electron
模組
npm install --save-dev @vscode/test-cli @vscode/test-electron
安裝模組後,您將擁有 vscode-test
命令列,您可以將其新增至 package.json
中的 scripts
區段
{
"name": "my-cool-extension",
"scripts": {
+ "test": "vscode-test"
vscode-test
會尋找相對於目前工作目錄的 .vscode-test.js/mjs/cjs
檔案。此檔案提供測試執行器的組態,您可以在此處找到完整的定義。
常見選項包括
- (必要)
files
- 包含要執行之測試的模式、模式清單或絕對路徑。 version
- 用於執行測試的 VS Code 版本 (預設為stable
)。workspaceFolder
- 測試期間要開啟的工作區路徑。extensionDevelopmentPath
- 您的擴充功能資料夾路徑 (預設為組態檔案的目錄)。mocha
- 包含要傳遞至 Mocha 的其他 選項 的物件。
組態可以很簡單,例如
// .vscode-test.js
const { defineConfig } = require('@vscode/test-cli');
module.exports = defineConfig({ files: 'out/test/**/*.test.js' });
...或更進階
// .vscode-test.js
const { defineConfig } = require('@vscode/test-cli');
module.exports = defineConfig([
{
label: 'unitTests',
files: 'out/test/**/*.test.js',
version: 'insiders',
workspaceFolder: './sampleWorkspace',
mocha: {
ui: 'tdd',
timeout: 20000
}
}
// you can specify additional test configurations, too
]);
如果您透過傳遞陣列來定義多個組態,則當您執行 vscode-test
時,它們會依序執行。您可以使用 --label
旗標依 label
篩選並個別執行它們,例如 vscode-test --label unitTests
。執行 vscode-test --help
以取得完整的命令列選項集。
測試腳本
設定 CLI 後,您可以編寫和執行測試。測試腳本可以存取 VS Code API,並在 Mocha 下執行。以下是範例 (src/test/suite/extension.test.ts)
import * as assert from 'assert';
// 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', () => {
suiteTeardown(() => {
vscode.window.showInformationMessage('All tests done!');
});
test('Sample test', () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
您可以使用 npm test
命令,或在安裝 Extension Test Runner 後,使用 VS Code 中的 測試:執行所有測試 命令來執行此測試。您也可以使用 測試:偵錯所有測試 命令來偵錯測試。
進階設定:您自己的執行器
您可以在 helloworld-test-sample 中找到本指南的組態。本文的其餘部分將在範例的上下文中說明這些檔案
- 測試腳本 (
src/test/runTest.ts
) - 測試執行器腳本 (
src/test/suite/index.ts
)
VS Code 提供兩個 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>
測試腳本 (src/test/runTest.ts
) 使用 @vscode/test-electron
API 來簡化下載、解壓縮和啟動具有擴充功能測試參數的 VS Code 的流程
import * as path from 'path';
import { runTests } from '@vscode/test-electron';
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(err);
console.error('Failed to run tests');
process.exit(1);
}
}
main();
@vscode/test-electron
API 也允許
- 啟動具有特定工作區的 VS Code。
- 下載與最新穩定版本不同的 VS Code 版本。
- 啟動具有其他 CLI 參數的 VS Code。
您可以在 microsoft/vscode-test 找到更多 API 使用範例。
測試執行器腳本
執行擴充功能整合測試時,--extensionTestsPath
指向程式化執行測試套件的測試執行器腳本 (src/test/suite/index.ts
)。以下是 helloworld-test-sample
的 測試執行器腳本,其使用 Mocha 來執行測試套件。您可以將其用作起點,並使用 Mocha 的 API 自訂您的設定。您也可以將 Mocha 替換為任何其他可以程式化執行的測試架構。
import * as path from 'path';
import * as Mocha from 'mocha';
import { glob } from 'glob';
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true
});
const testsRoot = path.resolve(__dirname, '..');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot })
.then(files => {
// 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);
}
})
.catch(err => {
return e(err);
});
});
}
測試執行器腳本和 *.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.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
偵錯測試
偵錯測試與偵錯擴充功能類似。
以下是範例 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"]
}
]
}
提示
使用 Insiders 版本進行擴充功能開發
由於 VS Code 的限制,如果您使用 VS Code 穩定版本並嘗試在 CLI 上執行整合測試,則會擲回錯誤
Running extension tests from the command line is currently only supported if no other instance of Code is running.
一般而言,如果您從 CLI 執行擴充功能測試,則測試執行的版本不能已經在執行中。作為一種變通方法,您可以在 VS Code Stable 中執行測試,並使用 VS Code Insiders 進行開發。只要您不是從 VS Code Insiders 中的 CLI 執行測試,而是在 VS Code Stable 中執行,此設定就能正常運作。
另一種替代方案是從 VS Code 本身內的偵錯啟動組態執行擴充功能測試。這樣做還有一個額外的好處,就是您甚至可以偵錯測試。
在偵錯時停用其他擴充功能
當您在 VS Code 中偵錯擴充功能測試時,VS Code 會使用全域安裝的 VS Code 執行個體,並載入所有已安裝的擴充功能。您可以將 --disable-extensions
組態新增至 launch.json
或 @vscode/test-electron
的 runTests
API 的 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"]
}
]
}
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']
});
使用 @vscode/test-electron
的自訂設定
有時您可能想要執行自訂設定,例如在開始測試之前執行 code --install-extension
以安裝另一個擴充功能。@vscode/test-electron
具有更細緻的 API 來容納這種情況
import * as cp from 'child_process';
import * as path from 'path';
import {
downloadAndUnzipVSCode,
resolveCliArgsFromVSCodeExecutablePath,
runTests
} from '@vscode/test-electron';
async function main() {
try {
const extensionDevelopmentPath = path.resolve(__dirname, '../../../');
const extensionTestsPath = path.resolve(__dirname, './suite/index');
const vscodeExecutablePath = await downloadAndUnzipVSCode('1.40.1');
const [cliPath, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath);
// Use cp.spawn / cp.exec for custom setup
cp.spawnSync(
cliPath,
[...args, '--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,
extensionDevelopmentPath,
extensionTestsPath
});
} catch (err) {
console.error('Failed to run tests');
process.exit(1);
}
}
main();
後續步驟
- 持續整合 - 在持續整合服務 (例如 Azure DevOps) 中執行您的擴充功能測試。