Skip to content

Commit 08e228d

Browse files
Introduce autoTestDiscoverOnSavePattern configuration option (#24728)
Closes #24817 ## What this change does Introduce `autoTestDiscoverOnSavePattern` configuration option to control `autoTestDiscoverOnSaveEnabled` behavior to only attempt test discovery refresh when files matching the specified glob pattern are saved. ## Why this change In a Python project we have with over 40K tests, developers definitely notice issues when pytest discovery is running whenever any file in the workspace is saved, despite all tests matching a very consistent pattern (`./tests/**/test_*.py`). ## Other alternatives I considered I did consider trying to match only the specific patterns used by unittest/pytest here. Given that would require parsing underlying configuration files / raw args in the test configuration for the workspace for both unittest and pytest (plus any other test runners supported in future) - I don't think that's going to be easy to maintain. Plus the addition / deletion of `__init__.py` files play a significant part in test discovery despite not being covered by the test configuration pattern - so this solution would be incomplete. Another alternative would be to accept a parent directory and only include python files from that directory + subdirectories (using workspace directory as default value). This avoids introducing a glob configuration value, but feels very limiting. --------- Co-authored-by: Eleanor Boyd <[email protected]>
1 parent 79e8a13 commit 08e228d

File tree

6 files changed

+15
-2
lines changed

6 files changed

+15
-2
lines changed

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,12 @@
657657
"scope": "resource",
658658
"type": "boolean"
659659
},
660+
"python.testing.autoTestDiscoverOnSavePattern": {
661+
"default": "**/*.py",
662+
"description": "%python.testing.autoTestDiscoverOnSavePattern.description%",
663+
"scope": "resource",
664+
"type": "string"
665+
},
660666
"python.testing.cwd": {
661667
"default": null,
662668
"description": "%python.testing.cwd.description%",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"python.terminal.focusAfterLaunch.description": "When launching a python terminal, whether to focus the cursor on the terminal.",
7575
"python.terminal.launchArgs.description": "Python launch arguments to use when executing a file in the terminal.",
7676
"python.testing.autoTestDiscoverOnSaveEnabled.description": "Enable auto run test discovery when saving a test file.",
77+
"python.testing.autoTestDiscoverOnSavePattern.description": "Glob pattern used to determine which files are used by autoTestDiscoverOnSaveEnabled.",
7778
"python.testing.cwd.description": "Optional working directory for tests.",
7879
"python.testing.debugPort.description": "Port number used for debugging of tests.",
7980
"python.testing.promptToConfigure.description": "Prompt to configure a test framework if potential tests directories are discovered.",

resources/report_issue_user_settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@
7979
"pytestPath": "placeholder",
8080
"unittestArgs": "placeholder",
8181
"unittestEnabled": true,
82-
"autoTestDiscoverOnSaveEnabled": true
82+
"autoTestDiscoverOnSaveEnabled": true,
83+
"autoTestDiscoverOnSavePattern": "placeholder"
8384
},
8485
"terminal": {
8586
"activateEnvironment": true,

src/client/common/configSettings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ export class PythonSettings implements IPythonSettings {
320320
unittestEnabled: false,
321321
pytestPath: 'pytest',
322322
autoTestDiscoverOnSaveEnabled: true,
323+
autoTestDiscoverOnSavePattern: '**/*.py',
323324
} as ITestingSettings;
324325
}
325326
}
@@ -336,6 +337,7 @@ export class PythonSettings implements IPythonSettings {
336337
unittestArgs: [],
337338
unittestEnabled: false,
338339
autoTestDiscoverOnSaveEnabled: true,
340+
autoTestDiscoverOnSavePattern: '**/*.py',
339341
};
340342
this.testing.pytestPath = getAbsolutePath(systemVariables.resolveAny(this.testing.pytestPath), workspaceRoot);
341343
if (this.testing.cwd) {

src/client/testing/configuration/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface ITestingSettings {
1111
unittestArgs: string[];
1212
cwd?: string;
1313
readonly autoTestDiscoverOnSaveEnabled: boolean;
14+
readonly autoTestDiscoverOnSavePattern: string;
1415
}
1516

1617
export type TestSettingsPropertyNames = {

src/client/testing/testController/controller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { inject, injectable, named } from 'inversify';
55
import { uniq } from 'lodash';
6+
import * as minimatch from 'minimatch';
67
import {
78
CancellationToken,
89
TestController,
@@ -552,7 +553,8 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
552553
private watchForTestContentChangeOnSave(): void {
553554
this.disposables.push(
554555
onDidSaveTextDocument(async (doc: TextDocument) => {
555-
if (doc.fileName.endsWith('.py')) {
556+
const settings = this.configSettings.getSettings(doc.uri);
557+
if (minimatch.default(doc.uri.fsPath, settings.testing.autoTestDiscoverOnSavePattern)) {
556558
traceVerbose(`Testing: Trigger refresh after saving ${doc.uri.fsPath}`);
557559
this.sendTriggerTelemetry('watching');
558560
this.refreshData.trigger(doc.uri, false);

0 commit comments

Comments
 (0)