Go Testing Best Practices
This skill provides actionable testing guidelines. For detailed implementation patterns, code examples, rationale, and production system references, consult go-testing-best-practices.md.
When Working with Go Tests
Always apply these current best practices:
1. Test Organisation
- Place test files alongside source code using
*_test.go naming
- Use internal tests (same package) for unit testing unexported functions
- Use external tests (
package foo_test) for integration testing and examples
- Split test files by functionality when they exceed 500-800 lines (e.g.,
handler_auth_test.go, handler_validation_test.go)
2. Table-Driven Testing
- Prefer map-based tables over slice-based for automatic unique test names
- Use descriptive test case names that appear in failure output
- See detailed guide for complete pattern and examples
3. Concurrent Testing
- Use
testing/synctest for deterministic concurrent testing (Go 1.24+)
- This eliminates flaky time-based tests and runs in microseconds instead of seconds
- For traditional parallel tests, always call
t.Parallel() first in test functions
4. Assertions and Comparisons
- Use
cmp.Diff() from google/go-cmp for complex comparisons
- Standard library is sufficient for simple tests
- Testify is the dominant third-party framework when richer assertions are needed
5. Mocking and Test Doubles
- Favour integration testing with real dependencies over heavy mocking
- Use Testcontainers for database/service integration tests
- When mocking is necessary, prefer simple function-based test doubles over code generation
- Use interface-based design ("accept interfaces, return structs")
6. Coverage Targets
- Aim for 70-80% coverage as a practical target
- Focus on meaningful tests over percentage metrics
- Use
go test -cover and go tool cover -html for analysis
7. Test Fixtures
- Use
testdata directory for test fixtures (automatically ignored by Go toolchain)
- Implement golden file testing for validating complex output
- Use functional builder patterns for complex test data
8. Helpers and Cleanup
- Always mark helper functions with
t.Helper() for accurate error reporting
- Use
t.Cleanup() for resource cleanup (superior to defer in tests)
9. Benchmarking (Go 1.24+)
- Use
B.Loop() method as the preferred pattern (prevents compiler optimisations)
- Combine with
benchstat for statistical analysis
- Use
-benchmem for memory profiling
10. Naming Conventions
- Test functions:
Test*, Benchmark*, Fuzz*, Example* (capital letter after prefix)
- Use
got and want for actual vs expected values
- Use descriptive test case names in table-driven tests
Integration vs Unit Testing
- Separate tests by environment variable (preferred over build tags)
- See detailed guide for implementation pattern
Additional Reference Material
Load go-testing-best-practices.md when you need:
- Complete code examples for table-driven tests, mocking patterns, golden files, helpers, or benchmarks
- Detailed explanation of testing/synctest concurrent testing patterns
- Rationale behind why specific patterns are preferred over alternatives
- Production system examples and statistics (Kubernetes, Docker, Uber, Netflix, ByteDance)
- Context on testing framework choices (Testify, GoMock, Testcontainers)
- Comprehensive coverage strategies and tooling details
- Integration testing patterns with containerisation
The detailed guide contains full context, examples with explanations, and production-proven patterns. This SKILL.md provides the actionable rules to apply.
Key Principle
Focus on meaningful tests that validate behaviour rather than implementation. Pragmatic excellence over theoretical perfection.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: writing-go-tests3description: Applies current Go testing best practices. Use when writing or modifying Go test files or advising on Go testing strategies. Use when this capability is needed.4---56# Go Testing Best Practices78This skill provides actionable testing guidelines. For detailed implementation patterns, code examples, rationale, and production system references, consult `go-testing-best-practices.md`.910## When Working with Go Tests1112**Always apply these current best practices:**1314### 1. Test Organisation15- Place test files alongside source code using `*_test.go` naming16- Use internal tests (same package) for unit testing unexported functions17- Use external tests (`package foo_test`) for integration testing and examples18- Split test files by functionality when they exceed 500-800 lines (e.g., `handler_auth_test.go`, `handler_validation_test.go`)1920### 2. Table-Driven Testing21- **Prefer map-based tables over slice-based** for automatic unique test names22- Use descriptive test case names that appear in failure output23- See detailed guide for complete pattern and examples2425### 3. Concurrent Testing26- **Use `testing/synctest` for deterministic concurrent testing** (Go 1.24+)27- This eliminates flaky time-based tests and runs in microseconds instead of seconds28- For traditional parallel tests, always call `t.Parallel()` first in test functions2930### 4. Assertions and Comparisons31- Use `cmp.Diff()` from `google/go-cmp` for complex comparisons32- Standard library is sufficient for simple tests33- Testify is the dominant third-party framework when richer assertions are needed3435### 5. Mocking and Test Doubles36- **Favour integration testing with real dependencies** over heavy mocking37- Use Testcontainers for database/service integration tests38- When mocking is necessary, prefer simple function-based test doubles over code generation39- Use interface-based design ("accept interfaces, return structs")4041### 6. Coverage Targets42- Aim for **70-80% coverage as a practical target**43- Focus on meaningful tests over percentage metrics44- Use `go test -cover` and `go tool cover -html` for analysis4546### 7. Test Fixtures47- Use `testdata` directory for test fixtures (automatically ignored by Go toolchain)48- Implement golden file testing for validating complex output49- Use functional builder patterns for complex test data5051### 8. Helpers and Cleanup52- **Always mark helper functions with `t.Helper()`** for accurate error reporting53- Use `t.Cleanup()` for resource cleanup (superior to defer in tests)5455### 9. Benchmarking (Go 1.24+)56- **Use `B.Loop()` method** as the preferred pattern (prevents compiler optimisations)57- Combine with `benchstat` for statistical analysis58- Use `-benchmem` for memory profiling5960### 10. Naming Conventions61- Test functions: `Test*`, `Benchmark*`, `Fuzz*`, `Example*` (capital letter after prefix)62- Use `got` and `want` for actual vs expected values63- Use descriptive test case names in table-driven tests6465## Integration vs Unit Testing6667- **Separate tests by environment variable** (preferred over build tags)68- See detailed guide for implementation pattern6970## Additional Reference Material7172**Load `go-testing-best-practices.md` when you need:**73- Complete code examples for table-driven tests, mocking patterns, golden files, helpers, or benchmarks74- Detailed explanation of testing/synctest concurrent testing patterns75- Rationale behind why specific patterns are preferred over alternatives76- Production system examples and statistics (Kubernetes, Docker, Uber, Netflix, ByteDance)77- Context on testing framework choices (Testify, GoMock, Testcontainers)78- Comprehensive coverage strategies and tooling details79- Integration testing patterns with containerisation8081**The detailed guide contains full context, examples with explanations, and production-proven patterns. This SKILL.md provides the actionable rules to apply.**8283## Key Principle8485**Focus on meaningful tests that validate behaviour rather than implementation.** Pragmatic excellence over theoretical perfection.8687---88> Converted and distributed by [TomeVault](https://tomevault.io/claim/torosent) — claim your Tome and manage your conversions.89<!-- tomevault:4.0:skill_md:2026-04-13 -->