Skip to content

Commit ce9883d

Browse files
committed
project labeling
1 parent b0504d1 commit ce9883d

File tree

5 files changed

+29
-6
lines changed

5 files changed

+29
-6
lines changed

.github/instructions/testing_feature_area.instructions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ This approach was chosen because:
201201
2. Implementing custom exclusion would add significant complexity with minimal benefit
202202
3. The existing approach is transparent and predictable - each project shows what it finds
203203

204+
### Empty projects and hidden root nodes
205+
206+
**Important:** If a project discovers zero tests, its root node will **not appear** in the Test Explorer. This is by design - the test tree only shows projects that have actual tests.
207+
204208
### Logging prefix
205209

206210
All project-based testing logs use the `[test-by-project]` prefix for easy filtering in the output channel.

src/client/testing/testController/common/resultResolver.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,23 @@ export class PythonResultResolver implements ITestResultResolver {
3333
*/
3434
private projectId?: string;
3535

36+
/**
37+
* Optional project display name for labeling the test tree root.
38+
* When set, the root node label will be "project: {projectName}" instead of the folder name.
39+
*/
40+
private projectName?: string;
41+
3642
constructor(
3743
testController: TestController,
3844
testProvider: TestProvider,
3945
private workspaceUri: Uri,
4046
projectId?: string,
47+
projectName?: string,
4148
) {
4249
this.testController = testController;
4350
this.testProvider = testProvider;
4451
this.projectId = projectId;
52+
this.projectName = projectName;
4553
// Initialize a new TestItemIndex which will be used to track test items in this workspace/project
4654
this.testItemIndex = new TestItemIndex();
4755
}
@@ -76,6 +84,7 @@ export class PythonResultResolver implements ITestResultResolver {
7684
this.testProvider,
7785
token,
7886
this.projectId,
87+
this.projectName,
7988
);
8089
sendTelemetryEvent(EventName.UNITTEST_DISCOVERY_DONE, undefined, {
8190
tool: this.testProvider,

src/client/testing/testController/common/testDiscoveryHandler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export class TestDiscoveryHandler {
2929
testProvider: TestProvider,
3030
token?: CancellationToken,
3131
projectId?: string,
32+
projectName?: string,
3233
): void {
3334
if (!payload) {
3435
// No test data is available
@@ -70,6 +71,7 @@ export class TestDiscoveryHandler {
7071
},
7172
token,
7273
projectId,
74+
projectName,
7375
);
7476
}
7577
}

src/client/testing/testController/common/testProjectRegistry.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,23 @@ export class TestProjectRegistry {
192192

193193
// Create test infrastructure
194194
const testProvider = this.getTestProvider(workspaceUri);
195-
const resultResolver = new PythonResultResolver(this.testController, testProvider, workspaceUri, projectId);
195+
const projectDisplayName = createProjectDisplayName(pythonProject.name, pythonEnvironment.version);
196+
const resultResolver = new PythonResultResolver(
197+
this.testController,
198+
testProvider,
199+
workspaceUri,
200+
projectId,
201+
pythonProject.name, // Use simple project name for test tree label (without version)
202+
);
196203
const { discoveryAdapter, executionAdapter } = createTestAdapters(
197204
testProvider,
198205
resultResolver,
199206
this.configSettings,
200207
this.envVarsService,
201208
);
202209

203-
const projectName = createProjectDisplayName(pythonProject.name, pythonEnvironment.version);
204-
205210
return {
206-
projectName,
211+
projectName: projectDisplayName,
207212
projectUri: pythonProject.uri,
208213
workspaceUri,
209214
pythonProject,

src/client/testing/testController/common/utils.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,15 @@ export function populateTestTree(
213213
testItemMappings: ITestItemMappings,
214214
token?: CancellationToken,
215215
projectId?: string,
216+
projectName?: string,
216217
): void {
217218
// If testRoot is undefined, use the info of the root item of testTreeData to create a test item, and append it to the test controller.
218219
if (!testRoot) {
219220
// Create project-scoped ID if projectId is provided
220221
const rootId = projectId ? `${projectId}${PROJECT_ID_SEPARATOR}${testTreeData.path}` : testTreeData.path;
221-
testRoot = testController.createTestItem(rootId, testTreeData.name, Uri.file(testTreeData.path));
222+
// Use "Project: {name}" label for project-based testing, otherwise use folder name
223+
const rootLabel = projectName ? `Project: ${projectName}` : testTreeData.name;
224+
testRoot = testController.createTestItem(rootId, rootLabel, Uri.file(testTreeData.path));
222225

223226
testRoot.canResolveChildren = true;
224227
testRoot.tags = [RunTestTag, DebugTestTag];
@@ -282,7 +285,7 @@ export function populateTestTree(
282285

283286
testRoot!.children.add(node);
284287
}
285-
populateTestTree(testController, child, node, testItemMappings, token, projectId);
288+
populateTestTree(testController, child, node, testItemMappings, token, projectId, projectName);
286289
}
287290
}
288291
});

0 commit comments

Comments
 (0)