VS Codeのエージェントモードを拡張するには、を試してください!

拡張機能のテスト

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.jsonscripts セクションに追加できます。

{
  "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 で確認できます。このドキュメントの残りの部分では、サンプルを例にこれらのファイルを説明します。

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 Stable でテストを実行し、開発には VS Code Insiders を使用できます。VS Code Insiders でCLIからテストを実行するのではなく、VS Code Stable で実行する限り、この設定は問題なく動作します。

代替案として、VS Code 自体の中からデバッグ起動構成から拡張機能テストを実行する方法があります。これには、テストをデバッグできるという追加の利点があります。

デバッグ中に他の拡張機能を無効にする

VS Code で拡張機能テストをデバッグすると、VS Code はグローバルにインストールされている VS Code のインスタンスを使用し、インストールされているすべての拡張機能を読み込みます。launch.json--disable-extensions 設定を追加するか、@vscode/test-electronrunTests 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();

次のステップ