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
It would be great if there were tool calls for Test Explorer:
-Run All Tests
-Run Individual Test or Class or Test Tree Node
-Fetch list of remaining failed tests or un-run tests
-Fetch count of passing\failed\skipped\un-run tests
-Run tests in debug mode
-Run Test Coverage analyzer
-Fetch specific Module\class Coverage percentage or the fully expanded coverage tree details
Optional nice to haves:
-Execute VS terminal commands, just like GitHub Copilot does (so that it can run stuff like OpenCover commands)
@SG-FVSP Some of these seem possible, but I'm not able to find VS SDK APIs for a number of them. I'm not sure how GH Copilot is doing it (they probably have internal access to other features the rest of us don't)
@SG-FVSP Following up on my earlier comment — I went back and dug through the actual VS assemblies (VS 2022 17.14 and VS 2026 18.0) rather than just hunting the docs, and I was wrong about a few of these. Revising:
✅ What we can do
1. Run All Tests / Debug All Tests TestExplorer.RunAllTests / TestExplorer.DebugAllTests.
2. Run / Debug by class or method TestExplorer.RunAllTestsInContext / TestExplorer.DebugAllTestsInContext. These are caret-context based, so the tool drives the caret to the target class/method first, then invokes.
3. Wait for a run to actually finish, and report when it does
This one I'd missed. IOperationState in Microsoft.VisualStudio.TestWindow.Interfaces.dll raises state changes off the TestOperationStates enum — TestExecutionStarting, TestExecutionStarted, TestExecutionFinished, DiscoveryFinished, TestExecutionCanceling, etc. That means the run/debug tools can await real completion instead of firing and returning immediately, which is what makes everything below actually useful.
4. Counts of passing / failed / skipped / un-run
I flat out missed this one — it's public API, and it's exactly what you asked for:
It's MEF-exported by TestExplorerStatsService, so IComponentModel.GetService<ITestExplorerStatsService>() gets you there. Public surface is identical between VS 2022 and VS 2026.
5. Kick off the coverage analyzer Test.AnalyzeCodeCoverageForAllTests, plus Test.CodeCoverageResults to surface the window. Caveat in the "can't" section below.
6. Read coverage numbers
Two routes, both workable:
Portable: shell out to dotnet-coverage / Microsoft.CodeCoverage.Console to convert .coverage → Cobertura and parse. Works on both VS versions and actually gives proper module/class/method rollups.
7. Execute terminal commands ITerminalService is a real brokered service (Microsoft.VisualStudio.Terminal.TerminalService) — CreateTerminalAsync, AttachTerminalStreamAsync (bidirectional stream), GetTerminalGuidsAsync, ShowAsync, CloseAsync. Identical across both VS versions. Caveat below.
❌ What we can't do (and why)
1. Fetch the list of specific failed / un-run tests by name
This is the one that's genuinely walled off, and I can now say exactly why. The per-test detail lives in TestResultDetails, TestNodeDetailsSummary and TestWindowViewModel — all internal to Microsoft.VisualStudio.TestWindow.Core / .Internal. TestWindow.Core.dll carries:
and Microsoft.VisualStudio.TestWindow.Copilot.Internal.dll references those internal types 50+ times.
So — to answer my own earlier question about how Copilot does it: it's InternalsVisibleTo gated on Microsoft's strong-name key. Not something a third-party extension can obtain. Reflection would technically work in-process, but it's unsupported and would break silently on any VS update, so I'm not shipping that.
The public API gives us aggregate counts and nothing more granular. If you need actual test names + outcomes, the practical path is running via vstest.console.exe / dotnet test with a TRX logger and parsing the result — but that's a separate run from Test Explorer's own state, not a read of it.
2. Class / module-level coverage tree straight from VS
VS 2026's coverage contracts only expose per-file and per-line data. There's no class or module rollup in the API — you'd have to aggregate spans yourself and use Roslyn to map them back to symbols. The dotnet-coverage → Cobertura route gives you that hierarchy for free, so that's the better answer if you want the expanded tree.
3. Coverage at all on VS 2022 Community / Professional
Code coverage was Enterprise-only through VS 2022. It became available in all editions in VS 2026 — I confirmed this on disk (CommonExtensions\Microsoft\AnalyzeCodeCoverage\ exists in VS 2026 Community, not in VS 2022 Community). So any coverage tool has to degrade gracefully rather than assume it's there.
AttachTerminalStreamAsync hands back a raw PTY stream — ANSI escape codes, no command boundaries, no exit codes. Fine for "run this and let the user watch it in VS," not fine for "run OpenCover and tell me whether it succeeded." For the latter I'd rather use a plain process-execution tool that can actually return an exit code and clean stdout/stderr.
Net: this moves from 4-of-8 to roughly 6.5-of-8. I'll split the workable pieces into separate issues — test run/debug with real completion tracking, stats, terminal, and coverage. Thanks for pushing on this one, the stats API in particular was a good catch to go back for.
Keeping this issue open as the umbrella until those land.
The one item with no path forward is the list of individual failed / un-run test names — that stays blocked on InternalsVisibleTo and isn't tracked separately, since there's nothing actionable to do about it.
Correction to my assessment above, found while implementing #104 (PR #107).
I said the module/class coverage tree was out of reach:
2. Class / module-level coverage tree straight from VS — VS 2026's coverage contracts only expose per-file and per-line data. There's no class or module rollup in the API.
That was true of Microsoft.CodeCoverage.VisualStudio.Contracts (IReportService), which is what I looked at. I missed a better assembly.
Microsoft.CodeCoverage.IO.dll — at Common7\IDE\CommonExtensions\Microsoft\TestWindow\VsTest, present in VS 2022 and VS 2026, every edition — exposes:
Function carries TypeName and NamespaceName, so grouping by declaring type gives the module → class → method tree. ModuleWrapper and Function both derive from CoverageStatistics, so the counts are pre-computed.
-Fetch specific Module\class Coverage percentage or the fully expanded coverage tree details
is supported, on both VS 2022 and VS 2026, in any edition. It shipped as coverage_report in #107. One caveat: running coverage is still edition-gated (Enterprise only through VS 2022, all editions from VS 2026) — but reading an existing .coverage file works everywhere.
Seven of eight. The one genuine hard stop remains the names of individual failed or un-run tests — that data is internal to Microsoft.VisualStudio.TestWindow.Core and gated behind InternalsVisibleTo on Microsoft's strong-name key, as detailed earlier in this thread. test_stats gives the counts; for names, running via vstest.console.exe / dotnet test with a TRX logger and parsing the result remains the workaround.
Leaving this issue open until the four PRs have been exercised against a live Visual Studio.
Activity
CalvinAllen commentedon Jul 8, 2026
@SG-FVSP Some of these seem possible, but I'm not able to find VS SDK APIs for a number of them. I'm not sure how GH Copilot is doing it (they probably have internal access to other features the rest of us don't)
What I'm seeing right now is that I can add -
The rest don't have APIs I can tap into
CalvinAllen commentedon Sep 3, 2026
@SG-FVSP Following up on my earlier comment — I went back and dug through the actual VS assemblies (VS 2022 17.14 and VS 2026 18.0) rather than just hunting the docs, and I was wrong about a few of these. Revising:
✅ What we can do
1. Run All Tests / Debug All Tests
TestExplorer.RunAllTests/TestExplorer.DebugAllTests.2. Run / Debug by class or method
TestExplorer.RunAllTestsInContext/TestExplorer.DebugAllTestsInContext. These are caret-context based, so the tool drives the caret to the target class/method first, then invokes.3. Wait for a run to actually finish, and report when it does
This one I'd missed.
IOperationStateinMicrosoft.VisualStudio.TestWindow.Interfaces.dllraises state changes off theTestOperationStatesenum —TestExecutionStarting,TestExecutionStarted,TestExecutionFinished,DiscoveryFinished,TestExecutionCanceling, etc. That means the run/debug tools can await real completion instead of firing and returning immediately, which is what makes everything below actually useful.4. Counts of passing / failed / skipped / un-run
I flat out missed this one — it's public API, and it's exactly what you asked for:
It's MEF-exported by
TestExplorerStatsService, soIComponentModel.GetService<ITestExplorerStatsService>()gets you there. Public surface is identical between VS 2022 and VS 2026.5. Kick off the coverage analyzer
Test.AnalyzeCodeCoverageForAllTests, plusTest.CodeCoverageResultsto surface the window. Caveat in the "can't" section below.6. Read coverage numbers
Two routes, both workable:
IReportService.GetReportAsync()returnsCoverageRunData→CoverageFileData { Path, LinesCovered, LinesNotCovered, LinesPartiallyCovered, LineCoverageData[] }, with per-lineCovered/NotCovered/PartiallyCoveredstatus.dotnet-coverage/Microsoft.CodeCoverage.Consoleto convert.coverage→ Cobertura and parse. Works on both VS versions and actually gives proper module/class/method rollups.7. Execute terminal commands
ITerminalServiceis a real brokered service (Microsoft.VisualStudio.Terminal.TerminalService) —CreateTerminalAsync,AttachTerminalStreamAsync(bidirectional stream),GetTerminalGuidsAsync,ShowAsync,CloseAsync. Identical across both VS versions. Caveat below.❌ What we can't do (and why)
1. Fetch the list of specific failed / un-run tests by name
This is the one that's genuinely walled off, and I can now say exactly why. The per-test detail lives in
TestResultDetails,TestNodeDetailsSummaryandTestWindowViewModel— allinternaltoMicrosoft.VisualStudio.TestWindow.Core/.Internal.TestWindow.Core.dllcarries:and
Microsoft.VisualStudio.TestWindow.Copilot.Internal.dllreferences those internal types 50+ times.So — to answer my own earlier question about how Copilot does it: it's
InternalsVisibleTogated on Microsoft's strong-name key. Not something a third-party extension can obtain. Reflection would technically work in-process, but it's unsupported and would break silently on any VS update, so I'm not shipping that.The public API gives us aggregate counts and nothing more granular. If you need actual test names + outcomes, the practical path is running via
vstest.console.exe/dotnet testwith a TRX logger and parsing the result — but that's a separate run from Test Explorer's own state, not a read of it.2. Class / module-level coverage tree straight from VS
VS 2026's coverage contracts only expose per-file and per-line data. There's no class or module rollup in the API — you'd have to aggregate spans yourself and use Roslyn to map them back to symbols. The
dotnet-coverage→ Cobertura route gives you that hierarchy for free, so that's the better answer if you want the expanded tree.3. Coverage at all on VS 2022 Community / Professional
Code coverage was Enterprise-only through VS 2022. It became available in all editions in VS 2026 — I confirmed this on disk (
CommonExtensions\Microsoft\AnalyzeCodeCoverage\exists in VS 2026 Community, not in VS 2022 Community). So any coverage tool has to degrade gracefully rather than assume it's there.4. Terminal command execution with reliable exit codes / output parsing
AttachTerminalStreamAsynchands back a raw PTY stream — ANSI escape codes, no command boundaries, no exit codes. Fine for "run this and let the user watch it in VS," not fine for "run OpenCover and tell me whether it succeeded." For the latter I'd rather use a plain process-execution tool that can actually return an exit code and clean stdout/stderr.Net: this moves from 4-of-8 to roughly 6.5-of-8. I'll split the workable pieces into separate issues — test run/debug with real completion tracking, stats, terminal, and coverage. Thanks for pushing on this one, the stats API in particular was a good catch to go back for.
CalvinAllen commentedon Sep 3, 2026
Split the workable pieces out into their own issues:
feat(tools): add test run and debug tools with completion trackingfeat(tools): add test statistics toolfeat(tools): add visual studio terminal toolsfeat(tools): add code coverage toolsKeeping this issue open as the umbrella until those land.
The one item with no path forward is the list of individual failed / un-run test names — that stays blocked on
InternalsVisibleToand isn't tracked separately, since there's nothing actionable to do about it.feat(tools): add Visual Studio terminal tools (#106)
CalvinAllen commentedon Sep 3, 2026
Correction to my assessment above, found while implementing #104 (PR #107).
I said the module/class coverage tree was out of reach:
That was true of
Microsoft.CodeCoverage.VisualStudio.Contracts(IReportService), which is what I looked at. I missed a better assembly.Microsoft.CodeCoverage.IO.dll— atCommon7\IDE\CommonExtensions\Microsoft\TestWindow\VsTest, present in VS 2022 and VS 2026, every edition — exposes:FunctioncarriesTypeNameandNamespaceName, so grouping by declaring type gives the module → class → method tree.ModuleWrapperandFunctionboth derive fromCoverageStatistics, so the counts are pre-computed.@SG-FVSP — this means your request
is supported, on both VS 2022 and VS 2026, in any edition. It shipped as
coverage_reportin #107. One caveat: running coverage is still edition-gated (Enterprise only through VS 2022, all editions from VS 2026) — but reading an existing.coveragefile works everywhere.Updated status of this issue
test_run_all(#105)test_run(#105)test_debug_all,test_debug(#105)test_stats(#105)coverage_analyze(#107)coverage_report(#107)terminal_run(#106)Seven of eight. The one genuine hard stop remains the names of individual failed or un-run tests — that data is internal to
Microsoft.VisualStudio.TestWindow.Coreand gated behindInternalsVisibleToon Microsoft's strong-name key, as detailed earlier in this thread.test_statsgives the counts; for names, running viavstest.console.exe/dotnet testwith a TRX logger and parsing the result remains the workaround.Leaving this issue open until the four PRs have been exercised against a live Visual Studio.