現已釋出!閱讀關於 11 月新增功能和修復的內容。

測試擴充套件

Visual Studio Code 支援為你的擴充套件執行和除錯測試。這些測試將在一個名為擴充套件開發主機的特殊 VS Code 例項中執行,並可以完全訪問 VS Code API。我們將這些測試稱為整合測試,因為它們超越了無需 VS Code 例項即可執行的單元測試。本文件重點介紹 VS Code 整合測試。

概述

如果你使用Yeoman Generator來腳手架化你的擴充套件,整合測試已經為你建立好了。

在生成的擴充套件中,你可以使用 npm run testyarn 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.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 中使用Test: Run All Tests命令來執行。你也可以使用Test: Debug All Tests命令來除錯測試。

高階設定:你自己的執行器

你可以在helloworld-test-sample中找到此指南的配置。本文件的其餘部分將在示例的上下文中解釋這些檔案。

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 穩定版中執行測試,並在開發中使用VS Code Insiders。只要你不從 CLI 在 VS Code Insiders 中執行測試,而是在 VS Code 穩定版中執行,此設定就可以正常工作。

另一種方法是從 VS Code 內部的除錯啟動配置中執行擴充套件測試。這還有一個額外的優點,你可以除錯測試。

除錯時停用其他擴充套件

當你除錯 VS Code 中的擴充套件測試時,VS Code 將使用全域性安裝的 VS Code 例項並載入所有已安裝的擴充套件。你可以將 --disable-extensions 配置新增到 launch.json@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();

後續步驟

  • 持續整合 - 在 Azure DevOps 等持續整合服務中執行你的擴充套件測試。
© . This site is unofficial and not affiliated with Microsoft.