Skip to content

Commit 25f7180

Browse files
Add the "Configure Unit Tests" command. (#4303)
1 parent 0418d92 commit 25f7180

12 files changed

Lines changed: 149 additions & 29 deletions

File tree

.github/test_plan.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ class FailingTests(unittest.TestCase):
273273
- [ ] `Run Test` works
274274
- [ ] `Debug Test` works
275275
- [ ] Module/suite setup methods are also run (run the `test_setup` method to verify)
276+
- [ ] `Configure Unit Tests` works
277+
- [ ] quick pick for framework (and its settings)
278+
- [ ] selected framework enabled in workspace settings
279+
- [ ] framework's config added (and old config removed)
280+
- [ ] other frameworks disabled in workspace settings
276281

277282
#### [`pytest`](https://code.visualstudio.com/docs/python/unit-testing#_pytest-configuration-settings)
278283
```python

news/1 Enhancements/4286.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add the command 'Configure Unit Tests'.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"onCommand:python.enableLinting",
8585
"onCommand:python.createTerminal",
8686
"onCommand:python.discoverTests",
87+
"onCommand:python.configureTests",
8788
"onCommand:python.datascience.showhistorypane",
8889
"onCommand:python.datascience.importnotebook",
8990
"onCommand:python.datascience.selectjupyteruri",
@@ -212,6 +213,11 @@
212213
"title": "%python.command.python.discoverTests.title%",
213214
"category": "Python"
214215
},
216+
{
217+
"command": "python.configureTests",
218+
"title": "%python.command.python.configureTests.title%",
219+
"category": "Python"
220+
},
215221
{
216222
"command": "python.execSelectionInTerminal",
217223
"title": "%python.command.python.execSelectionInTerminal.title%",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"python.command.python.runCurrentTestFile.title": "Run Current Unit Test File",
1818
"python.command.python.runFailedTests.title": "Run Failed Unit Tests",
1919
"python.command.python.discoverTests.title": "Discover Unit Tests",
20+
"python.command.python.configureTests.title": "Configure Unit Tests",
2021
"python.command.python.execSelectionInTerminal.title": "Run Selection/Line in Python Terminal",
2122
"python.command.python.execSelectionInDjangoShell.title": "Run Selection/Line in Django Shell",
2223
"python.command.python.goToPythonObject.title": "Go to Python Object",

src/client/common/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export namespace Commands {
1818
export const Tests_View_UI = 'python.viewTestUI';
1919
export const Tests_Picker_UI = 'python.selectTestToRun';
2020
export const Tests_Picker_UI_Debug = 'python.selectTestToDebug';
21+
export const Tests_Configure = 'python.configureTests';
2122
export const Tests_Discover = 'python.discoverTests';
2223
export const Tests_Run_Failed = 'python.runFailedTests';
2324
export const Sort_Imports = 'python.sortImports';

src/client/telemetry/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export enum EventName {
3939
UNITTEST_STOP = 'UNITTEST.STOP',
4040
UNITTEST_RUN = 'UNITTEST.RUN',
4141
UNITTEST_DISCOVER = 'UNITTEST.DISCOVER',
42+
UNITTEST_CONFIGURE = 'UNITTEST.CONFIGURE',
4243
UNITTEST_VIEW_OUTPUT = 'UNITTEST.VIEW_OUTPUT',
4344
UNITTEST_NAVIGATE_TEST_FILE = 'UNITTEST.NAVIGATE.TEST_FILE',
4445
UNITTEST_NAVIGATE_TEST_FUNCTION = 'UNITTEST.NAVIGATE.TEST_FUNCTION',

src/client/telemetry/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ interface IEventNamePropertyMapping {
288288
[EventName.SELECT_LINTER]: LinterSelectionTelemetry;
289289
[EventName.SIGNATURE]: never | undefined;
290290
[EventName.SYMBOL]: never | undefined;
291+
[EventName.UNITTEST_CONFIGURE]: never | undefined;
291292
[EventName.TERMINAL_CREATE]: TerminalTelemetry;
292293
[EventName.UNITTEST_DISCOVER]: TestDiscoverytTelemetry;
293294
[EventName.UNITTEST_RUN]: TestRunTelemetry;

src/client/unittests/configuration.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ export class UnitTestConfigurationService implements IUnitTestConfigurationServi
2929
enabledCount += settings.unitTest.nosetestsEnabled ? 1 : 0;
3030
enabledCount += settings.unitTest.unittestEnabled ? 1 : 0;
3131
if (enabledCount > 1) {
32-
return this.promptToEnableAndConfigureTestFramework(wkspace, this.installer, this.outputChannel, 'Enable only one of the test frameworks (unittest, pytest or nosetest).', true);
32+
return this._promptToEnableAndConfigureTestFramework(wkspace, this.installer, this.outputChannel, 'Enable only one of the test frameworks (unittest, pytest or nosetest).', true);
3333
} else {
3434
const option = 'Enable and configure a Test Framework';
3535
const item = await this.appShell.showInformationMessage('No test framework configured (unittest, pytest or nosetest)', option);
3636
if (item === option) {
37-
return this.promptToEnableAndConfigureTestFramework(wkspace, this.installer, this.outputChannel);
37+
return this._promptToEnableAndConfigureTestFramework(wkspace, this.installer, this.outputChannel);
3838
}
3939
return Promise.reject(null);
4040
}
@@ -82,7 +82,17 @@ export class UnitTestConfigurationService implements IUnitTestConfigurationServi
8282
});
8383
}
8484

85-
private async promptToEnableAndConfigureTestFramework(wkspace: Uri, installer: IInstaller, outputChannel: OutputChannel, messageToDisplay: string = 'Select a test framework/tool to enable', enableOnly: boolean = false) {
85+
public async promptToEnableAndConfigureTestFramework(wkspace: Uri) {
86+
await this._promptToEnableAndConfigureTestFramework(wkspace, this.installer, this.outputChannel, undefined, false);
87+
}
88+
89+
private async _promptToEnableAndConfigureTestFramework(
90+
wkspace: Uri,
91+
installer: IInstaller,
92+
outputChannel: OutputChannel,
93+
messageToDisplay: string = 'Select a test framework/tool to enable',
94+
enableOnly: boolean = false
95+
) {
8696
const selectedTestRunner = await this.selectTestRunner(messageToDisplay);
8797
if (typeof selectedTestRunner !== 'number') {
8898
return Promise.reject(null);

src/client/unittests/main.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { IServiceContainer } from '../ioc/types';
2121
import { ITestTreeViewProvider } from '../providers/types';
2222
import { EventName } from '../telemetry/constants';
23-
import { sendTelemetryEvent } from '../telemetry/index';
23+
import { captureTelemetry, sendTelemetryEvent } from '../telemetry/index';
2424
import { activateCodeLenses } from './codeLenses/main';
2525
import {
2626
CANCELLATION_REASON, CommandSource, TEST_OUTPUT_CHANNEL
@@ -309,10 +309,27 @@ export class UnitTestManagementService implements IUnitTestManagementService, Di
309309
this.testResultDisplay.displayProgressStatus(promise, debug);
310310
await promise;
311311
}
312+
312313
private async registerSymbolProvider(symbolProvider: DocumentSymbolProvider): Promise<void> {
313314
const testCollectionStorage = this.serviceContainer.get<ITestCollectionStorageService>(ITestCollectionStorageService);
314315
this.disposableRegistry.push(activateCodeLenses(this.onDidChange, symbolProvider, testCollectionStorage));
315316
}
317+
318+
@captureTelemetry(EventName.UNITTEST_CONFIGURE, undefined, false)
319+
private async configureTests(resource?: Uri) {
320+
let wkspace: Uri | undefined;
321+
if (resource) {
322+
const wkspaceFolder = this.workspaceService.getWorkspaceFolder(resource);
323+
wkspace = wkspaceFolder ? wkspaceFolder.uri : undefined;
324+
} else {
325+
wkspace = await selectTestWorkspace();
326+
}
327+
if (!wkspace) {
328+
return;
329+
}
330+
const configurationService = this.serviceContainer.get<IUnitTestConfigurationService>(IUnitTestConfigurationService);
331+
await configurationService.promptToEnableAndConfigureTestFramework(wkspace!);
332+
}
316333
private registerCommands(): void {
317334
const disposablesRegistry = this.serviceContainer.get<Disposable[]>(IDisposableRegistry);
318335
const commandManager = this.serviceContainer.get<ICommandManager>(ICommandManager);
@@ -321,7 +338,14 @@ export class UnitTestManagementService implements IUnitTestManagementService, Di
321338
commandManager.registerCommand(constants.Commands.Tests_Discover, (_, cmdSource: CommandSource = CommandSource.commandPalette, resource?: Uri) => {
322339
// Ignore the exceptions returned.
323340
// This command will be invoked from other places of the extension.
324-
this.discoverTests(cmdSource, resource, true, true).ignoreErrors();
341+
this.discoverTests(cmdSource, resource, true, true)
342+
.ignoreErrors();
343+
}),
344+
commandManager.registerCommand(constants.Commands.Tests_Configure, (_, cmdSource: CommandSource = CommandSource.commandPalette, resource?: Uri) => {
345+
// Ignore the exceptions returned.
346+
// This command will be invoked from other places of the extension.
347+
this.configureTests(resource)
348+
.ignoreErrors();
325349
}),
326350
commandManager.registerCommand(constants.Commands.Tests_Run_Failed, (_, cmdSource: CommandSource = CommandSource.commandPalette, resource: Uri) => this.runTestsImpl(cmdSource, resource, undefined, true)),
327351
commandManager.registerCommand(constants.Commands.Tests_Run, (_, cmdSource: CommandSource = CommandSource.commandPalette, file: Uri, testToRun?: TestsToRun) => this.runTestsImpl(cmdSource, file, testToRun)),
@@ -346,7 +370,8 @@ export class UnitTestManagementService implements IUnitTestManagementService, Di
346370
if (!settings.unitTest.autoTestDiscoverOnSaveEnabled) {
347371
return;
348372
}
349-
this.discoverTestsForDocument(doc).ignoreErrors();
373+
this.discoverTestsForDocument(doc)
374+
.ignoreErrors();
350375
}
351376
private registerHandlers() {
352377
const documentManager = this.serviceContainer.get<IDocumentManager>(IDocumentManager);

src/client/unittests/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface IUnitTestConfigurationService {
1313
displayTestFrameworkError(wkspace: Uri): Promise<void>;
1414
selectTestRunner(placeHolderMessage: string): Promise<UnitTestProduct | undefined>;
1515
enableTest(wkspace: Uri, product: UnitTestProduct);
16+
promptToEnableAndConfigureTestFramework(wkspace: Uri);
1617
}
1718

1819
export const ITestResultDisplay = Symbol('ITestResultDisplay');

0 commit comments

Comments
 (0)