You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracking the user-reported testing regressions and performance complaints that emerged after the project-structure / [test-by-project] rework, plus the older follow-ups that ride alongside them.
The work is grouped into four problem areas. Each item below points at the existing user-filed issue (or a new engineering issue where there is no good match) so progress is visible in one place.
Problem areas (what users are reporting)
Test discovery is much slower than CLI pytest.
Multiple users on large parametrized suites — 30k tests take 40s in the Test Explorer vs ~2s on the CLI; 328k tests take 66s vs ~10s. The O(n²) list scans and oversized discovery payload have been addressed; follow-up work remains on line-number/path compaction and validating the end-to-end improvement.
Test tree is rebuilt from scratch on every change.
Saving any .py file re-discovers the whole workspace and wipes the existing tree. While re-discovery is in flight, users can't re-run or debug a test because the items have been cleared. "Debug: Restart" breaks for the same reason.
Run / debug pipeline regressions.
Tests appear as "skipped" even though they ran; debug runs can lose results when the result pipe closes; pytest-subtests failures get reported as success; the env selected via the Python Environments API is not always honored.
Hard discovery failures still open.
Smaller correctness bugs in the pytest plugin (HIDDEN_PARAM, pipe writer broken by mock.patch("builtins.open")).
Surface an error payload when the env-extension subprocess exits non-zero. Legacy path already does this in pytestExecutionAdapter.ts; the env-extension path resolves the deferred silently. With no results and no error, every test defaults to skipped. — Python skip all Tests #25892
pytest.HIDDEN_PARAM discovery crash.process_parameterized_test does parent_part, parameterized_section = test_node["name"].split("[", 1), which raises ValueError when pytest emits a node id without [...] (i.e. when HIDDEN_PARAM is used). One-line guard. — pytest.HIDDEN_PARAM Causes Discovery Failure #25795
Telemetry step 2 (Python-side). Add a meta block to the vscode_pytest discovery payload with subprocessDurationMs, pluginDurationMs, payloadBytes, parametrizedTestCount, and fold it into the new UNITTEST.DISCOVERY.DONE event so we can split slow discoveries into "subprocess vs plugin vs JS overhead". — new issue
Verify useEnvExtension() actually fires in VS Code 1.106+. Reporter pins a regression to that VS Code release. Telemetry-first: add an envSource field to the discovery/run events, look at the live data, then fix. — pytest discovery does not use specified environment #25718
non-test share drops to ~0%; rebuiltFromScratch=false share grows as incremental updates land.
Run / debug pipeline
UNITTEST.RUN.DONE.missingCount > 0 share; pipeClosedEarly share; failureCategory distribution
missingCount>0 and pipeClosedEarly shares drop to near-0 on mode='project' and debugging=true.
Discovery hard failures
UNITTEST.DISCOVERY.DONE.failureCategory distribution
Each individual fix shrinks its corresponding bucket.
Per-area success criteria are checked off as each fix ships and the telemetry confirms the change.
Out of scope (deliberately, for now)
Per-test or per-file names in telemetry — privacy-sensitive, not needed for the questions above.
True added / removed counts in UNITTEST.TREE.UPDATE — needs an O(n) set diff per discovery; revisit only if beforeCount/afterCount + rebuiltFromScratch aren't enough signal.
Migrating off named pipes entirely — out of scope for this workstream.
Tracking the user-reported testing regressions and performance complaints that emerged after the project-structure /
[test-by-project]rework, plus the older follow-ups that ride alongside them.The work is grouped into four problem areas. Each item below points at the existing user-filed issue (or a new engineering issue where there is no good match) so progress is visible in one place.
Problem areas (what users are reporting)
Test discovery is much slower than CLI pytest.
Multiple users on large parametrized suites — 30k tests take 40s in the Test Explorer vs ~2s on the CLI; 328k tests take 66s vs ~10s. The
O(n²)list scans and oversized discovery payload have been addressed; follow-up work remains on line-number/path compaction and validating the end-to-end improvement.Test tree is rebuilt from scratch on every change.
Saving any
.pyfile re-discovers the whole workspace and wipes the existing tree. While re-discovery is in flight, users can't re-run or debug a test because the items have been cleared. "Debug: Restart" breaks for the same reason.Run / debug pipeline regressions.
Tests appear as "skipped" even though they ran; debug runs can lose results when the result pipe closes;
pytest-subtestsfailures get reported as success; the env selected via the Python Environments API is not always honored.Hard discovery failures still open.
Smaller correctness bugs in the pytest plugin (
HIDDEN_PARAM, pipe writer broken bymock.patch("builtins.open")).Order of execution (impact × effort)
python.testing.autoTestDiscoverOnSavePatterndefault so saving a non-test file does not trigger a full re-discovery. Default today is**/*.py; change it to conventional pytest/unittest filenames plusconftest.py, while preserving custom user patterns. Implementation and regression tests are complete locally; publication is pending. —python.testing.autoTestDiscoverOnSaveEnabledis running test discovery on change to any file (not just test files) #25866vscode_pytest. Removed theO(n²)scans that dominate heavily parametrized suites. — Extremely slow test discovery when using pytest for large test suite #25973, completed by Improve performance of pytest discovery for large test suites #25974pytestExecutionAdapter.ts; the env-extension path resolves the deferred silently. With no results and no error, every test defaults to skipped. — Python skip all Tests #25892pytest-subtestsreports before publishing the final test outcome. Multiple call-phase reports share onenodeid; the currentcollected_tests_so_fardedup makes the first report win, so a later failing subtest or final failure can be discarded. — failingpytesttests are marked as “success” when some of the subtests succeeded #25824populateTestTree. TodayprocessDiscoverydoestestItemIndex.clear()andpopulateTestTreealways rebuilds. Diff old vs new test trees and only insert / remove / update changed items. Largest item; biggest user-visible fix; should land last. — After latest update: Testing tree of python tests reloads completely rather than just update #25822pytest.HIDDEN_PARAMdiscovery crash.process_parameterized_testdoesparent_part, parameterized_section = test_node["name"].split("[", 1), which raisesValueErrorwhen pytest emits a node id without[...](i.e. whenHIDDEN_PARAMis used). One-line guard. — pytest.HIDDEN_PARAM Causes Discovery Failure #25795metablock to thevscode_pytestdiscovery payload withsubprocessDurationMs,pluginDurationMs,payloadBytes,parametrizedTestCount, and fold it into the newUNITTEST.DISCOVERY.DONEevent so we can split slow discoveries into "subprocess vs plugin vs JS overhead". — new issuevscode_pytestpipe writer immune to mockedopen. When user test code doesmock.patch("builtins.open"), the pipe-writeropen()call gets intercepted and serialization breaks (surfaces asunsupported operand type(s) for +=: 'int' and 'NoneType'). Captureopenat import time before any test code can monkeypatch it. [vscode-pytest]: unsupported operand type(s) for +=: 'int' and 'NoneType' #25793 was closed as not planned after the information-request timeout; no fix landed. — new issue or reopen [vscode-pytest]: unsupported operand type(s) for +=: 'int' and 'NoneType' #25793useEnvExtension()actually fires in VS Code 1.106+. Reporter pins a regression to that VS Code release. Telemetry-first: add anenvSourcefield to the discovery/run events, look at the live data, then fix. — pytest discovery does not use specified environment #25718Closing as already resolved
printhas already been removed frompython_files/unittestadapter/execution.py.How we measure progress
Instrumentation status:
Each fix above has a corresponding metric so dashboards can verify the change actually moves the needle (and catch unintended regressions):
UNITTEST.DISCOVERY.DONE.totalDurationMsp50/p90 sliced bytestCountbucket ×modemode='project'converges tomode='legacy'.UNITTEST.DISCOVERY.TRIGGER.fileKind='non-test'share;UNITTEST.TREE.UPDATE.rebuiltFromScratchshare;msSinceLastTriggerp50non-testshare drops to ~0%;rebuiltFromScratch=falseshare grows as incremental updates land.UNITTEST.RUN.DONE.missingCount > 0share;pipeClosedEarlyshare;failureCategorydistributionmissingCount>0andpipeClosedEarlyshares drop to near-0 onmode='project'anddebugging=true.UNITTEST.DISCOVERY.DONE.failureCategorydistributionPer-area success criteria are checked off as each fix ships and the telemetry confirms the change.
Out of scope (deliberately, for now)
added/removedcounts inUNITTEST.TREE.UPDATE— needs anO(n)set diff per discovery; revisit only ifbeforeCount/afterCount+rebuiltFromScratcharen't enough signal.