Change:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --Version: 1.66.0 Commit: Date: 2022-03-30T05:50:04.419Z Electron: 17.2.0 Chromium: 98.0.4758.109 16.13.0 V8: 9.8.177.11-electron.0 OS: Darwin x64 21.4.0 Steps to Reproduce: a test controller register two items in the same location. in the testing gutter icon and observer that multiple items are listed, but cannot be distinguished. <img width="902" alt="Screen Shot 2022-04-06 at 3 49 30 PM" src="https://user-"In this case I have the following structure: These two test targets are parameterized to run with different configurations, so they appear as 2 different tests but have the same source location. This could happen with other structures, anything that results in 2 test items having overlapping locations.
We generally expect test extensions to generate distinct labels for the tests so that they can be distinguished, but in your case you have two tests with identical labels/names. How would you suggest fixing this?
I'm not sure, I might refactor how we manage our TestItem's to create multiple configurable profiles instead of multiple top level TestItems, but I think the general problem could still happen. If there is more than 1 test at a location, you could have the UI show the same structure as the test items, that might help. For example, either using the label: Or breaking those down into submenus
So, for reference, there is one other easy way to make this happen with a class based test system like XCTest. If I have a structure like: In the above example, you might end up with a structure like: So, that would pretty trivially replicate this issue of multiple test items having the same location in a more compact way than my initial post.
One approach we could take is to implement something like Get a list of while at least two test have the same set the conflicting tests' create the submenus for each Code pointer:
Hi everyone, I'm currently working on this issue :)
<!-- AUTHORVERIFICATIONREQUEST --This bug has been fixed in the latest release of ! you can help us out by commenting if things are now working as expected. If things still don't seem right, please ensure you're on version of Insiders (today's or later - you can use in the command palette to check), and leave a comment letting us know what isn't working as expected. Happy Coding!
Verification steps: the selfhost test provider in the VS Code repo this line to any click on the gutter decoration and verify that the suite and tests are distinguishable

Discussion:
allActions.push(new Action('testing.gutter.debugAll', localize('debug all test', 'Debug All Tests'), undefined, undefined, () => this.defaultDebug())); } <ins> const testItems = this.tests.map(testItem => ({ currentLabel: testItem.test.item.label, testItem, parent: testItem.test.parent, })); const getLabelConflicts = (tests: typeof testItems) => { const labelCount = new Map<string, number>(); for (const test of tests) { labelCount.set(test.currentLabel, (labelCount.get(test.currentLabel) || 0) + 1); } return tests.filter(e => labelCount.get(e.currentLabel)! > 1); }; let conflicts, hasParent = true; while ((conflicts = getLabelConflicts(testItems)).length && hasParent) { for (const conflict of conflicts) { if (conflict.parent) { const parent = this.testService.collection.getNodeById(conflict.parent); conflict.currentLabel = parent?.item.label + ' > ' + conflict.currentLabel; conflict.parent = parent?.parent ? parent.parent : null; } else { hasParent = false; } } } </ins> const disposable = new DisposableStore(); <del> const testSubmenus = this.tests.map(({ test, resultItem }) => { const actions = this.getTestContextMenuActions(test, resultItem); </del> <ins> const testSubmenus = testItems.map(({ currentLabel, testItem }) => { const actions = this.getTestContextMenuActions(testItem.test, testItem.resultItem); </ins> disposable.add(actions); <del> return new SubmenuAction(test.item.extId, stripIcons(test.item.label), actions.object); </del> <ins> return new SubmenuAction(testItem.test.item.extId, stripIcons(currentLabel), actions.object); </ins> }); return { object: Separator.join(allActions, testSubmenus), dispose: () => disposable.dispose() };