Run and Debug unit tests with flags
Asked Answered
S

4

7

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:

  1. This configuration works for vs code run test functionality:
"go.testFlags": [        
    "-ldflags",
    "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
]
  1. 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)

Stacystadholder answered 8/9, 2022 at 10:45 Comment(3)
Does Code use the same shell and the same environment as your terminal? Have you tried using ' (single-quote) instead of double-quote?Dorso
@Dorso your suggestion of using single quotes has helped me solve this partially, I've updated the question with my findings.Stacystadholder
Got it. Posted an answer. let me know how it goes.Dorso
M
2

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:

go test -c -gcflags="all=-N -l"

You can replace go test -c with go build, so I don't see why you wouldn't be able to simply use

go test -c -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" -gcflags="all=-N -l"

Then, you can start a dlv session in headless mode for your editor to connect to. Let's say go test -c generated a binary called "foo.test":

dlv exec ./foo.test  --headless --listen=:2345 --log --api-version=2    -- -count=1 -- $(pwd)/some/path

where -count=1 is a placeholder for the flags you would normally pass to go 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 running Debug: Open launch.json, which should look something like this:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Test",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "port": 2345,
            "host": "127.0.0.1",
            "showLog":true,
            "trace":"log"
        }
    ]
}

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)

Mainstream answered 15/9, 2022 at 17:3 Comment(0)
D
1

Have you tried this?

"go.testFlags": [        
    "-ldflags",
    "-X",
    "google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn"
]

When you create new tasks in VSCode you need to write each space-separated word/character as different parameters.

Driver answered 11/9, 2022 at 12:19 Comment(1)
tried it, but it generates the wrong command. getting this error after trying this solution: -X flag requires argument of the form importpath.name=valueStacystadholder
D
1

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:

"buildFlags": "-ldflags='-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn'",

It seems to work for both running and debugging the project.

Dorso answered 12/9, 2022 at 16:23 Comment(0)
B
0

I met the same problem and solved by setting env vars in settings.json like this:

    "go.toolsEnvVars": {
        "GOLANG_PROTOBUF_REGISTRATION_CONFLICT": "warn"
    },
Banket answered 30/6, 2023 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.