A Neovim plugin for running Go tests from within the editor. Uses Tree-sitter to intelligently
detect the test at the cursor, runs go test -v -json asynchronously, and renders results in a
split window with diagnostics.
- Detects the test under the cursor using Tree-sitter:
- Table-driven subtests (
{ name: "foo", ... }struct entries) t.Run("name", ...)subtests- The enclosing
Test*function - All tests in the file when the cursor is outside any test function
- Table-driven subtests (
- Runs
go test -v -jsonasynchronously — editor stays responsive vim.diagnosticmarkers on failed test function definitions- Reusable split window — reused across runs, not recreated
- Winbar shows the exact
go testcommand that was run :GoTestRetryto re-run the last test without moving the cursor
- Neovim ≥ 0.11
- nvim-treesitter with the Go parser installed
goavailable on$PATH
{
"vcraescu/gotest.nvim",
dependencies = { "nvim-treesitter/nvim-treesitter" },
cmd = { "GoTestNearest", "GoTestRetry" },
opts = {},
}The plugin registers no keymaps globally. Map the commands yourself:
vim.keymap.set("n", "<leader>tt", "<cmd>GoTestNearest<CR>", { desc = "Go: run nearest test" })
vim.keymap.set("n", "<leader>tr", "<cmd>GoTestRetry<CR>", { desc = "Go: retry last test" })| Command | Description |
|---|---|
:GoTestNearest |
Run the Go test nearest to the cursor |
:GoTestRetry |
Re-run the last executed test command |
Call require("gotest").setup(opts) with any overrides. All keys are optional.
require("gotest").setup({
view = {
height = 15, -- height of the output split in lines
focus_on_fail = true, -- focus the output pane on failure
focus_on_success = false,
show_on_fail = true, -- open the output pane on failure
show_on_success = true,
},
timeout = 30, -- go test -timeout value in seconds
disable_test_cache = false, -- pass -count=1 to disable go test cache
diagnostics = {
enabled = true, -- show vim.diagnostic markers on failed tests
},
})| Option | Default | Description |
|---|---|---|
view.height |
15 |
Height of the output split pane in lines |
view.focus_on_fail |
true |
Move cursor to the output pane when tests fail |
view.focus_on_success |
false |
Move cursor to the output pane when tests pass |
view.show_on_fail |
true |
Open the output pane when tests fail |
view.show_on_success |
true |
Open the output pane when tests pass |
timeout |
30 |
Test timeout passed to go test -timeout |
disable_test_cache |
false |
When true, always passes -count=1 to bypass the Go test cache |
diagnostics.enabled |
true |
Place vim.diagnostic warning markers on failed Test* function lines |
:GoTestNearest walks the Tree-sitter AST from the cursor position and resolves, in order:
- Table-driven subtest — cursor inside a
{ name: "my case", ... }struct literal entry t.Runsubtest — cursor inside at.Run("my case", func(t *testing.T) { ... })block- Enclosing
Test*function — cursor anywhere inside afunc TestFoo(t *testing.T)body - All tests in the file — cursor is outside any test function
The resulting -run flag uses \Q...\E POSIX quoting for exact name matching, with subtests
separated by /.
When diagnostics.enabled = true, a DiagnosticWarn marker with the message FAILED is placed
at the line of each failed func Test* definition. Diagnostics are cleared before every new run.