원클릭으로
vscode-testing-and-debugging
Guidance for testing and debugging VS Code extensions with the existing Mocha and @vscode/test-electron setup.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guidance for testing and debugging VS Code extensions with the existing Mocha and @vscode/test-electron setup.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Guidance for building, packaging, and releasing VS Code extensions with esbuild, vsce, and GitHub Actions workflows.
Guidance for implementing and modifying VS Code commands, menus, when clauses, and activation behavior.
Guidance for declaring, reading, updating, and reacting to VS Code extension configuration and settings changes safely.
Guidance for implementing and modifying VS Code extension architecture, activation flow, disposables, and extension-host-safe patterns.
Guidance for keeping VS Code extension localization, package.nls files, README content, and changelog updates in sync.
Guidance for implementing VS Code language features such as definitions, hovers, completions, symbols, diagnostics, formatting, and related providers.
| name | vscode-testing-and-debugging |
| description | Guidance for testing and debugging VS Code extensions with the existing Mocha and @vscode/test-electron setup. |
VS Code extensions are tested by running them inside a real (or headless) VS Code instance.
Tests use Mocha as the test framework and run via @vscode/test-cli / @vscode/test-electron.
Understanding the test harness and debugging setup is essential for writing reliable tests.
devDependencies)"@vscode/test-cli": "^0.0.12",
"@vscode/test-electron": "^2.4.1",
"@types/mocha": "^10.0.0"
.vscode-test.json Configuration{
"version": "1",
"tests": [
{
"workspaceFolder": "./src/test/fixtures",
"extensionDevelopmentPath": "${workspaceFolder}",
"files": "out/test/**/*.test.js"
}
]
}
package.json Scripts"scripts": {
"pretest": "tsc -p ./ && npm run lint",
"test": "vscode-test --config ./.vscode-test.json"
}
// src/test/extension.test.ts
import * as assert from 'assert';
import * as vscode from 'vscode';
suite('Extension Test Suite', () => {
suiteSetup(async () => {
// Wait for extension to activate
const ext = vscode.extensions.getExtension('publisher.extensionName');
if (ext && !ext.isActive) {
await ext.activate();
}
});
test('Extension should be present', () => {
assert.ok(vscode.extensions.getExtension('publisher.extensionName'));
});
test('Extension should activate', async () => {
const ext = vscode.extensions.getExtension('publisher.extensionName');
if (ext) {
await ext.activate();
assert.ok(ext.isActive);
}
});
test('Should register expected commands', async () => {
const commands = await vscode.commands.getCommands(true);
assert.ok(commands.includes('ext.myCommand'));
});
});
suite('Definition Provider Tests', () => {
let document: vscode.TextDocument;
suiteSetup(async () => {
const uri = vscode.Uri.file('/path/to/fixture.fxml');
document = await vscode.workspace.openTextDocument(uri);
});
test('Should provide definition for fx:controller', async () => {
const position = new vscode.Position(2, 20);
const locations = await vscode.commands.executeCommand<vscode.Location[]>(
'vscode.executeDefinitionProvider',
document.uri,
position
);
assert.ok(locations && locations.length > 0, 'Expected at least one definition');
});
});
test('Should execute openInSceneBuilder command', async () => {
// Commands that open external processes may be hard to assert;
// at minimum verify no uncaught exception is thrown.
const uri = vscode.Uri.file('/path/to/test.fxml');
await assert.doesNotReject(
() => vscode.commands.executeCommand('ext.openInSceneBuilder', uri)
);
});
test('Should read default configuration', () => {
const config = vscode.workspace.getConfiguration('myExt');
const enabled = config.get<boolean>('feature.enabled');
assert.strictEqual(enabled, true);
});
Place test fixture files in src/test/fixtures/. Common fixtures:
.fxml files with various element structuressettings.jsonsetup() / teardown().vscode.workspace.fs to create/delete temporary files in globalStorageUri rather than the real file system.VS Code tests require a display server. Use Xvfb in Linux CI:
# .github/workflows/build.yml
- name: Install Xvfb
run: sudo apt-get install -y xvfb
- name: Run tests
run: xvfb-run -a npm run test
Alternatively, use @vscode/test-electron with the --headless flag (VS Code 1.100+).
Add a launch configuration in .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/index"
],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
}
]
}
Extract pure functions and utilities from provider classes and test them with plain Mocha (no VS Code instance needed):
// src/utils/parseController.ts
export function parseControllerClassName(fxmlContent: string): string | undefined { ... }
// src/test/unit/parseController.test.ts
import * as assert from 'assert';
import { parseControllerClassName } from '../../utils/parseController';
suite('parseControllerClassName', () => {
test('Returns class name from fx:controller attribute', () => {
const xml = '<AnchorPane fx:controller="com.example.MyController" />';
assert.strictEqual(parseControllerClassName(xml), 'com.example.MyController');
});
test('Returns undefined for missing attribute', () => {
assert.strictEqual(parseControllerClassName('<AnchorPane />'), undefined);
});
});
vscode.commands.executeCommand('vscode.executeXxxProvider', ...).xvfb-run -a npm run test (or equivalent).