拡張機能のテスト
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 デスクトップでテストを実行できるようにする @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 は、拡張機能テストを実行するための 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>
テストスクリプト (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 を起動する。
その他の API 使用例は、microsoft/vscode-test で確認できます。
テストランナースクリプト
拡張機能の統合テストを実行するとき、--extensionTestsPath
は、プログラムでテストスイートを実行するテストランナースクリプト (src/test/suite/index.ts
) を指します。以下は、Mocha を使用してテストスイートを実行する helloworld-test-sample
のテストランナースクリプトです。これを開始点として使用し、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 安定版で実行し、開発にはVS Code Insiders を使用できます。VS Code Insiders で CLI からテストを実行せず、VS Code 安定版で実行する限り、このセットアップは問題なく動作します。
別の方法として、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 などの継続的インテグレーションサービスで拡張機能テストを実行します。