@@ -182,58 +182,110 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
182182
183183 public async activate ( ) : Promise < void > {
184184 const workspaces : readonly WorkspaceFolder [ ] = this . workspaceService . workspaceFolders || [ ] ;
185- workspaces . forEach ( ( workspace ) => {
186- const settings = this . configSettings . getSettings ( workspace . uri ) ;
187-
188- let discoveryAdapter : ITestDiscoveryAdapter ;
189- let executionAdapter : ITestExecutionAdapter ;
190- let testProvider : TestProvider ;
191- let resultResolver : PythonResultResolver ;
192185
193- if ( settings . testing . unittestEnabled ) {
194- testProvider = UNITTEST_PROVIDER ;
195- resultResolver = new PythonResultResolver ( this . testController , testProvider , workspace . uri ) ;
196- discoveryAdapter = new UnittestTestDiscoveryAdapter (
197- this . configSettings ,
198- resultResolver ,
199- this . envVarsService ,
200- ) ;
201- executionAdapter = new UnittestTestExecutionAdapter (
202- this . configSettings ,
203- resultResolver ,
204- this . envVarsService ,
205- ) ;
206- } else {
207- testProvider = PYTEST_PROVIDER ;
208- resultResolver = new PythonResultResolver ( this . testController , testProvider , workspace . uri ) ;
209- discoveryAdapter = new PytestTestDiscoveryAdapter (
210- this . configSettings ,
211- resultResolver ,
212- this . envVarsService ,
213- ) ;
214- executionAdapter = new PytestTestExecutionAdapter (
215- this . configSettings ,
216- resultResolver ,
217- this . envVarsService ,
186+ // Try to use project-based testing if enabled
187+ if ( this . useProjectBasedTesting ) {
188+ try {
189+ await Promise . all (
190+ Array . from ( workspaces ) . map ( async ( workspace ) => {
191+ try {
192+ // Discover projects in this workspace
193+ const projects = await this . discoverWorkspaceProjects ( workspace . uri ) ;
194+
195+ // Create map for this workspace
196+ const projectsMap = new Map < string , ProjectAdapter > ( ) ;
197+ projects . forEach ( ( project ) => {
198+ projectsMap . set ( project . projectId , project ) ;
199+ } ) ;
200+
201+ this . workspaceProjects . set ( workspace . uri , projectsMap ) ;
202+
203+ traceVerbose (
204+ `Discovered ${ projects . length } project(s) for workspace ${ workspace . uri . fsPath } ` ,
205+ ) ;
206+
207+ // Set up file watchers if auto-discovery is enabled
208+ const settings = this . configSettings . getSettings ( workspace . uri ) ;
209+ if ( settings . testing . autoTestDiscoverOnSaveEnabled ) {
210+ traceVerbose ( `Testing: Setting up watcher for ${ workspace . uri . fsPath } ` ) ;
211+ this . watchForSettingsChanges ( workspace ) ;
212+ this . watchForTestContentChangeOnSave ( ) ;
213+ }
214+ } catch ( error ) {
215+ traceError ( `Failed to activate project-based testing for ${ workspace . uri . fsPath } :` , error ) ;
216+ // Fall back to legacy mode for this workspace
217+ await this . activateLegacyWorkspace ( workspace ) ;
218+ }
219+ } ) ,
218220 ) ;
221+ return ;
222+ } catch ( error ) {
223+ traceError ( 'Failed to activate project-based testing, falling back to legacy mode:' , error ) ;
224+ this . useProjectBasedTesting = false ;
219225 }
226+ }
227+
228+ // Legacy activation (backward compatibility)
229+ workspaces . forEach ( ( workspace ) => {
230+ this . activateLegacyWorkspace ( workspace ) ;
231+ } ) ;
232+ }
220233
221- const workspaceTestAdapter = new WorkspaceTestAdapter (
222- testProvider ,
223- discoveryAdapter ,
224- executionAdapter ,
225- workspace . uri ,
234+ /**
235+ * Activates testing for a workspace using the legacy single-adapter approach.
236+ * Used for backward compatibility when project-based testing is disabled or unavailable.
237+ */
238+ private activateLegacyWorkspace ( workspace : WorkspaceFolder ) : void {
239+ const settings = this . configSettings . getSettings ( workspace . uri ) ;
240+
241+ let discoveryAdapter : ITestDiscoveryAdapter ;
242+ let executionAdapter : ITestExecutionAdapter ;
243+ let testProvider : TestProvider ;
244+ let resultResolver : PythonResultResolver ;
245+
246+ if ( settings . testing . unittestEnabled ) {
247+ testProvider = UNITTEST_PROVIDER ;
248+ resultResolver = new PythonResultResolver ( this . testController , testProvider , workspace . uri ) ;
249+ discoveryAdapter = new UnittestTestDiscoveryAdapter (
250+ this . configSettings ,
251+ resultResolver ,
252+ this . envVarsService ,
253+ ) ;
254+ executionAdapter = new UnittestTestExecutionAdapter (
255+ this . configSettings ,
256+ resultResolver ,
257+ this . envVarsService ,
258+ ) ;
259+ } else {
260+ testProvider = PYTEST_PROVIDER ;
261+ resultResolver = new PythonResultResolver ( this . testController , testProvider , workspace . uri ) ;
262+ discoveryAdapter = new PytestTestDiscoveryAdapter (
263+ this . configSettings ,
264+ resultResolver ,
265+ this . envVarsService ,
266+ ) ;
267+ executionAdapter = new PytestTestExecutionAdapter (
268+ this . configSettings ,
226269 resultResolver ,
270+ this . envVarsService ,
227271 ) ;
272+ }
273+
274+ const workspaceTestAdapter = new WorkspaceTestAdapter (
275+ testProvider ,
276+ discoveryAdapter ,
277+ executionAdapter ,
278+ workspace . uri ,
279+ resultResolver ,
280+ ) ;
228281
229- this . testAdapters . set ( workspace . uri , workspaceTestAdapter ) ;
282+ this . testAdapters . set ( workspace . uri , workspaceTestAdapter ) ;
230283
231- if ( settings . testing . autoTestDiscoverOnSaveEnabled ) {
232- traceVerbose ( `Testing: Setting up watcher for ${ workspace . uri . fsPath } ` ) ;
233- this . watchForSettingsChanges ( workspace ) ;
234- this . watchForTestContentChangeOnSave ( ) ;
235- }
236- } ) ;
284+ if ( settings . testing . autoTestDiscoverOnSaveEnabled ) {
285+ traceVerbose ( `Testing: Setting up watcher for ${ workspace . uri . fsPath } ` ) ;
286+ this . watchForSettingsChanges ( workspace ) ;
287+ this . watchForTestContentChangeOnSave ( ) ;
288+ }
237289 }
238290
239291 /**
0 commit comments