Skip to content

Commit 78865d0

Browse files
committed
fix to subtest issue
1 parent 7169c54 commit 78865d0

File tree

4 files changed

+337
-45
lines changed

4 files changed

+337
-45
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import { CancellationToken, TestController, TestItem, Uri, TestRun, FileCoverageDetail } from 'vscode';
55
import { CoveragePayload, DiscoveredTestPayload, ExecutionTestPayload, ITestResultResolver } from './types';
66
import { TestProvider } from '../../types';
7-
import { traceVerbose } from '../../../logging';
7+
import { traceInfo } from '../../../logging';
88
import { sendTelemetryEvent } from '../../../telemetry';
99
import { EventName } from '../../../telemetry/constants';
1010
import { TestItemIndex } from './testItemIndex';
@@ -24,8 +24,6 @@ export class PythonResultResolver implements ITestResultResolver {
2424
private static executionHandler: TestExecutionHandler = new TestExecutionHandler();
2525
private static coverageHandler: TestCoverageHandler = new TestCoverageHandler();
2626

27-
public subTestStats: Map<string, { passed: number; failed: number }> = new Map();
28-
2927
public detailedCoverageMap = new Map<string, FileCoverageDetail[]>();
3028

3129
constructor(testController: TestController, testProvider: TestProvider, private workspaceUri: Uri) {
@@ -71,13 +69,14 @@ export class PythonResultResolver implements ITestResultResolver {
7169
public resolveExecution(payload: ExecutionTestPayload | CoveragePayload, runInstance: TestRun): void {
7270
if ('coverage' in payload) {
7371
// coverage data is sent once per connection
74-
traceVerbose('Coverage data received.');
72+
traceInfo('Coverage data received, processing...');
7573
this.detailedCoverageMap = PythonResultResolver.coverageHandler.processCoverage(
7674
payload as CoveragePayload,
7775
runInstance,
7876
);
77+
traceInfo('Coverage data processing complete.');
7978
} else {
80-
this.subTestStats = PythonResultResolver.executionHandler.processExecution(
79+
PythonResultResolver.executionHandler.processExecution(
8180
payload as ExecutionTestPayload,
8281
runInstance,
8382
this.testItemIndex,

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ import { splitLines } from '../../../common/stringUtils';
88
import { splitTestNameWithRegex } from './utils';
99
import { clearAllChildren } from './testItemUtilities';
1010

11-
export interface SubtestStats {
12-
passed: number;
13-
failed: number;
14-
}
15-
1611
/**
1712
* Stateless handler for processing execution payloads and updating TestRun instances.
1813
* This handler is shared across all workspaces and contains no instance state.
@@ -21,27 +16,23 @@ export class TestExecutionHandler {
2116
/**
2217
* Process execution payload and update test run
2318
* Pure function - no instance state used
24-
* Returns subtest statistics for caller to manage
2519
*/
2620
public processExecution(
2721
payload: ExecutionTestPayload,
2822
runInstance: TestRun,
2923
testItemIndex: TestItemIndex,
3024
testController: TestController,
31-
): Map<string, SubtestStats> {
32-
const subtestStats = new Map<string, SubtestStats>();
25+
): void {
3326
const rawTestExecData = payload as ExecutionTestPayload;
3427

3528
if (rawTestExecData !== undefined && rawTestExecData.result !== undefined) {
3629
for (const keyTemp of Object.keys(rawTestExecData.result)) {
3730
const testItem = rawTestExecData.result[keyTemp];
3831

3932
// Delegate to specific outcome handlers
40-
this.handleTestOutcome(keyTemp, testItem, runInstance, testItemIndex, testController, subtestStats);
33+
this.handleTestOutcome(keyTemp, testItem, runInstance, testItemIndex, testController);
4134
}
4235
}
43-
44-
return subtestStats;
4536
}
4637

4738
/**
@@ -53,7 +44,6 @@ export class TestExecutionHandler {
5344
runInstance: TestRun,
5445
testItemIndex: TestItemIndex,
5546
testController: TestController,
56-
subtestStats: Map<string, SubtestStats>,
5747
): void {
5848
if (testItem.outcome === 'error') {
5949
this.handleTestError(runId, testItem, runInstance, testItemIndex, testController);
@@ -64,9 +54,9 @@ export class TestExecutionHandler {
6454
} else if (testItem.outcome === 'skipped') {
6555
this.handleTestSkipped(runId, runInstance, testItemIndex, testController);
6656
} else if (testItem.outcome === 'subtest-failure') {
67-
this.handleSubtestFailure(runId, testItem, runInstance, testItemIndex, testController, subtestStats);
57+
this.handleSubtestFailure(runId, testItem, runInstance, testItemIndex, testController);
6858
} else if (testItem.outcome === 'subtest-success') {
69-
this.handleSubtestSuccess(runId, runInstance, testItemIndex, testController, subtestStats);
59+
this.handleSubtestSuccess(runId, runInstance, testItemIndex, testController);
7060
}
7161
}
7262

@@ -168,17 +158,16 @@ export class TestExecutionHandler {
168158
runInstance: TestRun,
169159
testItemIndex: TestItemIndex,
170160
testController: TestController,
171-
subtestStats: Map<string, SubtestStats>,
172161
): void {
173162
const [parentTestCaseId, subtestId] = splitTestNameWithRegex(runId);
174163
const parentTestItem = testItemIndex.getTestItem(parentTestCaseId, testController);
175164

176165
if (parentTestItem) {
177-
const stats = subtestStats.get(parentTestCaseId);
166+
const stats = testItemIndex.getSubtestStats(parentTestCaseId);
178167
if (stats) {
179168
stats.failed += 1;
180169
} else {
181-
subtestStats.set(parentTestCaseId, {
170+
testItemIndex.setSubtestStats(parentTestCaseId, {
182171
failed: 1,
183172
passed: 0,
184173
});
@@ -213,17 +202,16 @@ export class TestExecutionHandler {
213202
runInstance: TestRun,
214203
testItemIndex: TestItemIndex,
215204
testController: TestController,
216-
subtestStats: Map<string, SubtestStats>,
217205
): void {
218206
const [parentTestCaseId, subtestId] = splitTestNameWithRegex(runId);
219207
const parentTestItem = testItemIndex.getTestItem(parentTestCaseId, testController);
220208

221209
if (parentTestItem) {
222-
const stats = subtestStats.get(parentTestCaseId);
210+
const stats = testItemIndex.getSubtestStats(parentTestCaseId);
223211
if (stats) {
224212
stats.passed += 1;
225213
} else {
226-
subtestStats.set(parentTestCaseId, { failed: 0, passed: 1 });
214+
testItemIndex.setSubtestStats(parentTestCaseId, { failed: 0, passed: 1 });
227215
clearAllChildren(parentTestItem);
228216
}
229217

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import { TestController, TestItem } from 'vscode';
55
import { traceError, traceVerbose } from '../../../logging';
66
import { getTestCaseNodes } from './testItemUtilities';
77

8+
export interface SubtestStats {
9+
passed: number;
10+
failed: number;
11+
}
12+
813
/**
914
* Maintains persistent ID mappings between Python test IDs and VS Code TestItems.
1015
* This is a stateful component that bridges discovery and execution phases.
@@ -21,11 +26,13 @@ export class TestItemIndex {
2126
private runIdToTestItem: Map<string, TestItem>;
2227
private runIdToVSid: Map<string, string>;
2328
private vsIdToRunId: Map<string, string>;
29+
private subtestStatsMap: Map<string, SubtestStats>;
2430

2531
constructor() {
2632
this.runIdToTestItem = new Map<string, TestItem>();
2733
this.runIdToVSid = new Map<string, string>();
2834
this.vsIdToRunId = new Map<string, string>();
35+
this.subtestStatsMap = new Map<string, SubtestStats>();
2936
}
3037

3138
/**
@@ -133,6 +140,21 @@ export class TestItemIndex {
133140
return testController.items.get(testItem.id) === testItem;
134141
}
135142

143+
/**
144+
* Get subtest statistics for a parent test case
145+
* Returns undefined if no stats exist yet for this parent
146+
*/
147+
public getSubtestStats(parentId: string): SubtestStats | undefined {
148+
return this.subtestStatsMap.get(parentId);
149+
}
150+
151+
/**
152+
* Set subtest statistics for a parent test case
153+
*/
154+
public setSubtestStats(parentId: string, stats: SubtestStats): void {
155+
this.subtestStatsMap.set(parentId, stats);
156+
}
157+
136158
/**
137159
* Remove all mappings
138160
* Called at the start of discovery to ensure clean state
@@ -141,6 +163,7 @@ export class TestItemIndex {
141163
this.runIdToTestItem.clear();
142164
this.runIdToVSid.clear();
143165
this.vsIdToRunId.clear();
166+
this.subtestStatsMap.clear();
144167
}
145168

146169
/**

0 commit comments

Comments
 (0)