skip to Main Content

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)

3

Answers


  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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. 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)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search