VSCode扩展测试调用executeCommand打开项目后测试无法推进
I've run into this exact headache before—vscode.openFolder is a tricky command for test environments because it doesn't just load a folder, it restarts the entire VSCode window to do so. That's why your tests are getting stuck: the original test runner process gets disconnected when the window reloads, leaving your tests in a limbo state where they can't finish executing or properly clean up.
Here's how to fix it, along with a breakdown of what's going wrong:
The Core Issue with vscode.openFolder
When you call vscode.openFolder, VSCode closes the current window and launches a brand new one with your target folder. This completely breaks your test context: the test runner running in the original window loses its connection, so tests either don't run fully, hang indefinitely, or leave the test window open requiring manual closure.
The Solution: Use workspace.updateWorkspaceFolders Instead
Instead of replacing the entire workspace (and restarting the window), use vscode.workspace.updateWorkspaceFolders to add your sample project to the existing workspace. This works within the current VSCode instance, so your test context stays intact and tests can run to completion.
Here's your modified test code with this fix:
import assert from 'assert'; import { after, before, it } from 'mocha'; import path from 'path'; import { Extension, extensions, Uri, window, workspace } from 'vscode'; suite('Extension Tests', () => { let extension: Extension<any>; const projectFolder = Uri.file(path.join(__dirname, '../../../test/suite/sample-project')); const originalWorkspaceFolders = workspace.workspaceFolders?.slice() || []; window.showInformationMessage('Start all tests.'); before(async () => { extension = extensions.getExtension('kshetline.ligatures-limited'); assert.ok(extension, 'Target extension not found'); // Clear existing workspace folders for a clean test slate await workspace.updateWorkspaceFolders(0, workspace.workspaceFolders?.length); // Add the sample project to the current workspace (no window restart!) await workspace.updateWorkspaceFolders(0, null, { uri: projectFolder }); // Ensure the extension is fully activated before running tests if (!extension.isActive) { await extension.activate(); } }); after(async () => { // Restore the original workspace state after tests finish await workspace.updateWorkspaceFolders(0, workspace.workspaceFolders?.length); originalWorkspaceFolders.forEach(folder => { workspace.updateWorkspaceFolders(workspace.workspaceFolders?.length || 0, null, folder); }); console.log('Test cleanup complete'); }); it('should load and activate extension', () => { assert.ok(extension); assert.ok(extension.isActive); }); it('second test should execute successfully', () => { assert.ok(true); }); });
Key Improvements in This Code:
- No window restart:
updateWorkspaceFoldersmodifies the workspace in-place, keeping your test runner connected to the active window. - Clean test environment: We clear existing workspace folders first to avoid interference from preloaded projects.
- Guaranteed extension activation: Explicitly activate the extension if it's not already running, ensuring your tests use a fully loaded extension.
- Workspace cleanup: Restore the original workspace state in the
afterhook to leave the test environment clean for subsequent runs.
Why Your Previous Fixes Didn't Work
Your attempts with async/await, done callbacks, and returning Promises were all correct for handling async operations—but the root issue wasn't async handling. It was the vscode.openFolder command itself destroying the test context. Switching to updateWorkspaceFolders eliminates that problem entirely.
内容的提问来源于stack exchange,提问作者kshetline

