Env
gopls version: master (5397e65c)
Proposal
GoLand offers a Go to test
shortcut (Ctrl+Shift+T
) that allows users to jump to test definitions (if any) or create a new test:
I propose to add a similar feature to gopls
. Initially, I was going to suggest to add a new command Go to TestXxx
to the Source Action
window (Alt+.
in VSCode), mimicking GoLand. However, I think implementing it as a CodeLens would be more convenient: users can immediately see what functions have tests.
An MVP implementation can be found at https://go.dev/cl/696395. Examples of Go to TestXxx
CodeLens for slices
package (actually, Go to {Test|Example|Benchmark|Fuzz}Xxx
):
Questions
-
I am not sure what algorithm should be used to match functions with their tests. A naive approach looks like this:
-
Try to find test functions that match name exactly:
TestFoo
forFoo
Test_foo
forfoo
TestBuffer_Bytes
for(Buffer).Bytes
-
Search with the capitalized first letter:
TestFoo
forfoo
TestBuffer_Bytes
for(buffer).Bytes
This algorithm should not have many false positives, but it fails to match
TestReplaceGrow
,TestReplacePanics
, etc. withslices.Replace
. We could use a prefix search like GoLand does, but I am not sure how to excludeTestDeleteFunc
from matches forDelete
:
- Maybe it's worth implementing this feature both as CodeLens and Source Action?
Pros | Cons | |
---|---|---|
CodeLens | - obvious which functions have tests - requires only a single click |
- requires a mouse click [0] - noisy when a function has many tests [1] |
Source Action | - easy to display all tests | - not obvious whether a function has tests - requires 3 actions: Alt+. , move selection, Enter |
- [0] Actually, it's possible to trigger CodeLens via keyboard, but there are some limitations - see microsoft/vscode#91232
- [1] Naive algorithm doesn't not produce that many CodeLenses
We could display only one test function (per type) as a CodeLens (with title like Go to TestXxx (has X more tests)
) and list all the test functions in the Source Actions menu. This approach should address all the mentioned issues.
Comment From: gabyhelp
Related Issues
- x/tools/gopls: better "run this test" UX #67400
- x/tools/gopls: story for custom codelens providers #40516
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: IlyasYOY
Hi! I think this is a fantastic idea and I’m really excited to see it land.
One suggestion I have is to avoid getting bogged down in finding a “perfect” algorithm for locating the corresponding tests right away. For an initial implementation it’s perfectly fine to rely on the existing naming conventions, especially for examples.
The Go blog defines the naming rules for Example
functions here: https://go.dev/blog/examples#example-function-names
func ExampleFoo() // documents the Foo function or type
func ExampleBar_Qux() // documents the Qux method of type Bar
func Example() // documents package as a whole
You can start by matching these patterns and, if possible, reuse any code that already handles them. Once the basic behavior is in place, the matching logic can be refined later.
Thanks for the great proposal – looking forward to seeing it in action!
Comment From: ShoshinNikita
One suggestion I have is to avoid getting bogged down in finding a “perfect” algorithm
Yeah, I agree. The linked CL already implements the "naive algorithm" I described in the issue description