Skip to content

Fix pytest discovery using workspace-root interpreter after missed startup environment events - #26195

Open
MOHAMMED WASIM KHAN (wasim-builds) wants to merge 1 commit into
microsoft:mainfrom
wasim-builds:fix-25718-pytest-discovery-env
Open

MOHAMMED WASIM KHAN (wasim-builds) wants to merge 1 commit into
microsoft:mainfrom
wasim-builds:fix-25718-pytest-discovery-env

Conversation

@wasim-builds

Copy link
Copy Markdown

Summary

Fixes #25718.

In a monorepo where a Python sub-project has its own environment (e.g. apps/example-py/.venv), pytest test discovery can run with the workspace-root interpreter (system Python, without pytest) instead of the project's environment, failing with No module named pytest. The reporter suspected a race between the Python Environments extension and the Python extension; this PR closes that race in the project-based test discovery flow ([test-by-project]).

Root cause

Project-based discovery intentionally falls back to a "default project" bound to the workspace-root interpreter when a project's environment has not been assigned yet, and relies on the environments extension's onDidChangeEnvironment / onDidChangePythonProjects events to re-discover once environments resolve. Two startup holes made that self-healing unreliable:

  1. Events raised before subscription were dropped. activate() awaited the initial discoverAndRegisterProjects() for every workspace before calling subscribeToProjectChanges() / subscribeToEnvironmentChanges(). Acquiring the environments API during that initial discovery is what activates the environments extension and kicks off its initial refresh, so the environment assignments produced by that refresh could fire into a window where nobody was listening. The workspace then stayed on the fallback default project (workspace-root interpreter) until a manual refresh or file save.

  2. Events arriving during initial registration were ignored. handleEnvironmentChange only queued workspaces for which projectRegistry.hasProjects() was already true. An environment assignment raised while a workspace's initial project discovery was still in flight (nothing registered yet) was dropped, with the same stuck-on-wrong-interpreter result.

Changes (src/client/testing/testController/controller.ts)

  • activate(): subscribe to project and environment changes before the initial project discovery, so no assignments are missed during startup.
  • handleEnvironmentChange(): queue re-discovery for any workspace that is not in legacy mode (i.e. has no legacy WorkspaceTestAdapter registered), instead of only workspaces with already-registered projects. Legacy-mode workspaces are still skipped; workspaces mid-registration are now covered.

No changes to the fallback default-project behavior itself, to discovery/execution adapters, or to interpreter resolution.

Tests

  • compile: npx tsc -p ./ passes.
  • Unit tests (npm run test:unittests mocha config): all PythonTestController and testing-controller suites pass (13/13 controller tests; 108/108 across the testController-related suites).
    • Updated ignores workspaces that are not in project-based mode to explicitly cover legacy mode (legacy adapter registered).
    • Added queues workspaces whose initial project registration is still in flight.
    • Added activate() subscribes to project and environment changes before initial project discovery (asserts call ordering).
  • Full unit run: the only failures are pre-existing, environment-dependent suites unrelated to this change (Terminal Environment Variable Collection Service conda-shell mocks, Native Python Finder binary tests); verified identical failures on a pristine upstream/main worktree.

Test plan / manual verification

I could not run the VS Code integration host here, so end-to-end verification with the reporter's monorepo example is still needed:

  1. Open the monorepo root with the Python Environments extension managing environments (project apps/example-py with its .venv).
  2. Reload the window and immediately open the Testing panel.
  3. Expected: no No module named pytest discovery error from the system Python; once the environments extension assigns the project environment, the workspace re-discovers automatically and the test tree is rooted at the project with its venv.

…d startup environment events

Subscribe to Python Environments extension project/environment changes
before the initial test project discovery, and queue re-discovery for
workspaces whose initial project registration is still in flight when an
environment is assigned. Previously, environment assignments raised
while initial discovery was running were missed entirely, leaving the
workspace stuck on the fallback default project that discovers tests
with the workspace-root (e.g. system) interpreter instead of the
project's environment.

Fixes microsoft#25718
Copilot AI balanced review requested due to automatic review settings October 4, 2026 20:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pytest discovery does not use specified environment

2 participants