I want to be able to run and debug unit tests within VS Code using the test explorer or code lens.
But in order to run my tests, I need to add this flag:
-ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
Therefore, in my vscode settings.json file, I have added this json:
"go.testFlags": [
"-ldflags",
""-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn""
]
Now when I click the Run Test button in test explorer or in the code lens, VS Code generates this command:
/opt/homebrew/bin/go test -timeout 30s -run ^TestCreateNamespace$ github.com/SomePath/SomeRepo/internal/models/v2 -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
but the test case fails with this error:
panic: proto: extension number 1042 is already registered on message google.protobuf.FileOptions
See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
And this is the exact error that I am expecting if I dont suply the -ldflags
in my go test command. But the surprising thing is that when I copy the exact same vs code generated test command mentioned above and run that in my terminal then the test case passes.
Along with running the tests from Vs Code, I would also like to be able to debug them by setting breakpoints and stepping through code.
Dev Environment: I am on an arm64 apple M1 Mac if that matters.
UPDATE: After fiddling around with the go.testFlags
values, I have found that:
- This configuration works for vs code
run test
functionality:
"go.testFlags": [
"-ldflags",
"-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
]
- This configuration works for vs code
debug test
functionality:
"go.testFlags": [
"-ldflags",
"'-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'"
]
(Notice the extra single quotes in debug configuration).
Now I need to find a single configuration that works for both run test
as well as debug test
functionalities, Or somehow specify 2 different configs for run test
and debug test
in settings.json
file of vs code so that I can use both functionalities without making changes to the settings.json
file every-time. (This might be a delve thing I suspect)
3
Answers
Have you tried this?
When you create new tasks in VSCode you need to write each space-separated word/character as different parameters.
I recommend using Launch Configuration instead of making changes in
settings.json
.So you need to create a file at
.vscode/launch.json
as instructed here and add the following line to the file:It seems to work for both running and debugging the project.
I can’t speak for VS Code, but when it comes to debugging tests that are a bit more complex to step through (e.g. godog cucumber-style tests) I usually compile the test binary like so:
You can replace
go test -c
withgo build
, so I don’t see why you wouldn’t be able to simply useThen, you can start a
dlv
session in headless mode for your editor to connect to. Let’s saygo test -c
generated a binary called "foo.test":where
-count=1
is a placeholder for the flags you would normally pass togo test
, and-- $(pwd)/some/path
could be (in case you have cucumber style tests) a path to a.feature
file. You can now connect your editor to the dlv session and start debugging. Asking some of my colleagues how that works in VSCode, they said something about a command palette and runningDebug: Open launch.json
, which should look something like this:Set the breakpoints, and you should be able to open the debug panel and run
Debug test
.In case anyone wonders, the flow for Vim is pretty much the same, except that there is no need for a json file. Using the
vim-go
plugin, once the dlv session is running, you set your breakpoints (:GoDebugBreakpoint
), and connect to dlv::GoDebugConnect 127.0.0.1:2345
.From that point on, it’s pretty much the same as any debug session
:GoDebugContinue
,:GoDebugStep
,:GoDebugStepOut
,:GoDebugPrint varname
and so on)