Using GoLand’s Built‑In Test Runner with Inline Coverage
See how GoLand’s gutter icons and coverage window give instant feedback on test execution and line‑level coverage, plus a short example showing how to improve coverage from 85% to 100%.
29 Jul 2025, 03:04 UTC

Problem: Getting fast, visible feedback on test coverage while coding
When you write Go tests, you often need to know whether a new test actually exercises the code you just changed. Switching to a terminal, running go test -cover, and then interpreting the output breaks the flow. GoLand solves this by integrating the test runner and coverage report directly into the editor.
How GoLand’s test runner works
GoLand automatically recognises files ending in _test.go. In the gutter (the vertical bar left of the line numbers) you see a small green triangle for each test function and a larger triangle for the whole file. Clicking the gutter icon opens a popup with options:
- Run – executes the test without coverage.
- Run with Coverage – adds the
-coverflag and shows line‑level results. - Debug – starts a Delve debugging session.
When you choose Run with Coverage, GoLand invokes the Go toolchain (go test -coverprofile=...) and captures the generated coverage profile. The IDE then paints each statement:
- Green background – the statement was executed at least once.
- Red background – the statement was not covered.
- No background – non‑executable lines (comments, blank lines).
A dedicated Coverage tool window appears at the bottom, showing the percentage per package and a list of files. Clicking a line in the window jumps to the corresponding source line, letting you navigate straight to uncovered code.
Worked example: raising coverage from 85% to 100%
Consider a simple HTTP handler in handler.go:
package handler
import "net/http"
func Hello(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" {
http.Error(w, "missing name", http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello, " + name)) // covered line
}
And its test in handler_test.go:
package handler
import "net/http/httptest"
func TestHello(t *testing.T) {
req := httptest.NewRequest("GET", "/hello?name=Alice", nil)
rr := httptest.NewRecorder()
Hello(rr, req)
if rr.Code != http.StatusOK {
t.Fatalf("expected status OK; got %v", rr.Code)
}
// missing test for the error case
}
Place the cursor inside TestHello and click the gutter icon → Run with Coverage. The coverage window shows:
- Package
handler: 85% coverage. - In the editor, the line
if name == "" {is red (not executed), while thew.Writeline is green.
To improve coverage, add a test for the empty‑name branch:
func TestHelloMissingName(t *testing.T) {
req := httptest.NewRequest("GET", "/hello", nil)
rr := httptest.NewRecorder()
Hello(rr, req)
if rr.Code != http.StatusBadRequest {
t.Fatalf("expected status BadRequest; got %v", rr.Code)
}
if rr.Body.String() != "missing name" {
t.Fatalf("unexpected body: %s", rr.Body.String())
}
}
Run the test suite again with coverage. The window now reports 100% for the package, and the previously red line turns green because the error branch was exercised.
Trade‑offs and limitations
Collecting coverage adds runtime overhead; large test suites can noticeably slow down each run. For rapid edit‑compile‑test cycles, you may prefer to run tests without coverage and enable it only when you need to verify a specific change. Additionally, GoLand’s line‑level highlighting depends on the Delve debugger version bundled with the IDE. If you manually install a different Delve, mismatched versions can cause missing or incorrect highlights. Keeping the IDE up‑to‑date avoids this issue.
Actionable closing
Next time you write or modify a Go test, try the gutter’s Run with Coverage action. Watch the green/red highlights appear instantly, use the coverage window to jump to untested lines, and add targeted tests until the red disappears. This tight feedback loop helps you maintain high test coverage without leaving the editor.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.