How to Debug Go Test Failures
In this tutorial, you'll learn about How to Debug Go Test Failures. We cover key concepts, practical examples, and best practices.
The Problem
You run go test and see:
--- FAIL: TestCalculateTotal (0.00s) main_test.go:25: expected 100, got 99 FAIL
The test failed, but you need more information to understand why and fix the code.
## Quick Fix
### Step 1: Run with verbose output
```bash
go test -v ./...
Expected:
=== RUN TestCalculateTotal
main_test.go:25: expected 100, got 99
--- FAIL: TestCalculateTotal (0.00s)
=== RUN TestParseInput
--- PASS: TestParseInput (0.00s)
FAIL
-v prints every test name and its result, not just failures.
Step 2: Run a specific test
go test -v -run TestCalculateTotal ./...
The -run flag matches a regex against test function names. This runs only matching tests, saving time in large suites.
Step 3: Run with race detection
go test -race ./...
Expected:
==================
WARNING: DATA RACE
Read at 0x00c0000a0f0 by goroutine 8:
myapp.TestConcurrentAccess()
/project/main_test.go:42 +0x45
==================
The race detector finds concurrent access bugs that would otherwise appear randomly in production.
Step 4: Show test coverage
go test -cover ./...
Expected:
ok myapp 0.123s coverage: 78.5% of statements
Step 5: Generate a coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
Open coverage.html in a browser. Green lines are covered, red lines are not.
Step 6: Run tests with a timeout
go test -timeout 30s ./...
Tests that hang beyond the timeout are killed with a stack trace. The default timeout is 10 minutes.
Step 7: Print logs from tests
go test -v ./... 2>&1
If your test uses t.Log() or fmt.Println, the output only appears with -v.
Step 8: Run tests in short mode
go test -short ./...
In the test file:
func TestIntegration(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
}
Use -short during development to skip slow integration tests.
Step 9: Run tests repeatedly to find flakes
go test -count=5 -run TestFlaky ./...
The -count flag runs the same test multiple times. Flaky tests that fail intermittently become visible.
Alternative Solutions
Use go test -json ./... for structured output that can be parsed by CI tools and IDEs.
Prevention
- Write table-driven tests to cover edge cases systematically.
- Run
go test -race ./...in CI to catch data races early. - Keep unit tests independent and parallelizable.
- Aim for at least 80% coverage on critical business logic.
- Use test coverage thresholds in CI to prevent coverage regression.
Common Errors
Test hanging indefinitely: If a test does not complete, it may be blocked on a channel or network call. Add a timeout: go test -timeout 5s. For individual tests, use ctx, cancel := context.WithTimeout(...).
Flaky tests: A test that passes sometimes and fails others is usually caused by shared state or race conditions. Run with -race and -count=10 to reproduce.
Missing test files: Tests must be in files named *_test.go. A file named helper_test.go is discovered, but test_helper.go is not.
Testing private functions: Go tests in the same package can access private functions. If the test is in package myapp_test (external test package), it only sees exported symbols. Switch to package myapp to test internals.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro