-
Notifications
You must be signed in to change notification settings - Fork 106
Description
I am using ctest, the test discovery in Visual Studio works great. However, if I try to debug a test after starting up Visual Studio, then I see the error message "ERROR: Debugging is only possible if GoogleTestAdapter has been installed into Visual Studio - NuGet installation does not support this (and other features such as Visual Studio Options, toolbar, and solution settings)."
The same behaviour is documented in this extension: https://marketplace.visualstudio.com/items?itemName=Overhatted.buck2
As indicated there, "... the setting "Use new test execution framework (experimental)" in "Tools" > "Options..." -> "Test Adapter for Google Test" needs to be switched for each Visual Studio instance. It doesn't matter the end result, simply changing the setting to the other value will make the debugger attach properly." It also does not matter what value is set upon startup, it needs to be changed before debugging works.
I checked the code and found the UseNewTestExecutionFramework setting. I asked Copilot (claude 4 sonnet) and it suggests:
"The problem is that when using the new test execution framework, the debugger attachment relies on a named pipe ID (DebuggingNamedPipeId) being available. This pipe ID is set up when the Visual Studio extension is properly loaded, but there seems to be a timing or initialization issue where this ID isn't always available when needed."
"The core issue is that the UseNewTestExecutionFramework requires a valid DebuggingNamedPipeId to be set up for debugging to work, but this ID might not be initialized properly when the test adapter loads before the Visual Studio extension is fully ready. The workaround you mentioned (toggling the setting) works because it forces a reinitialization of the debugging infrastructure."
I am unable to test or verify this hypothesis. It would be much appreciated if this were fixed! For completeness, Copilot suggests the following code changes:
TestExecutor.cs:
private bool IsDebuggingAllowed(IRunContext runContext)
{
// If not being debugged, always allow
if (!runContext.IsBeingDebugged)
return true;
// If using the old framework, debugging should work
if (!_settings.UseNewTestExecutionFramework)
return true;
// For new framework, check if VS process is available
// If not available, try to reinitialize the named pipe connection
if (!IsVisualStudioProcessAvailable())
{
// Attempt to reinitialize the debugging connection
// This handles cases where the extension wasn't fully loaded when tests started
TryReinitializeDebuggingConnection();
if (!IsVisualStudioProcessAvailable())
{
_logger.LogError(Resources.DebuggingMessage);
return false;
}
}
return true;
}
private void TryReinitializeDebuggingConnection()
{
try
{
// Force a refresh of the settings which should reload the debugging pipe ID
// This is a workaround for the timing issue where the extension loads after test discovery
var extensionOptionsPage = GoogleTestExtensionOptionsPage.GetInstance();
if (extensionOptionsPage != null)
{
// Trigger a settings refresh which should reinitialize the named pipe
extensionOptionsPage.RefreshSettings();
}
}
catch (Exception ex)
{
_logger.DebugInfo($"Failed to reinitialize debugging connection: {ex.Message}");
}
}GoogleTestExtensionOptionsPage.cs:
public void RefreshSettings()
{
// Reinitialize the debugging named pipe ID
_debuggingNamedPipeId = GetNewDebuggingNamedPipeId();
// Update the global run settings with the new pipe ID
_globalRunSettings.RunSettings = GetRunSettingsFromOptionPages();
// Refresh the UI to reflect any changes
RefreshVsUi();
}
private string GetNewDebuggingNamedPipeId()
{
// Generate a new named pipe ID for debugging
return Guid.NewGuid().ToString();
}