writing-go-tests
Applies current Go testing best practices. Use when writing or modifying Go test files or advising on Go testing strategies.
When & Why to Use This Skill
This Claude skill automates the application of modern Go testing best practices, ensuring high-quality, maintainable, and efficient test suites. It provides actionable guidance on table-driven testing, deterministic concurrency with Go 1.24 features, integration testing strategies, and performance benchmarking to help developers build robust Go applications.
Use Cases
- Refactoring legacy Go tests into modern, map-based table-driven tests for improved clarity and automatic unique test naming.
- Implementing deterministic concurrent testing using Go 1.24's synctest to eliminate flaky tests and reduce execution time from seconds to microseconds.
- Designing robust integration tests with real dependencies using Testcontainers to reduce reliance on fragile and complex mocking patterns.
- Optimizing performance benchmarks using the B.Loop() method and benchstat for reliable statistical analysis and memory profiling.
- Enhancing test suite maintainability and error reporting accuracy by applying t.Helper() and t.Cleanup() patterns.
| name | writing-go-tests |
|---|---|
| description | Applies current Go testing best practices. Use when writing or modifying Go test files or advising on Go testing strategies. |
| # model | inherit |
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.gonaming - 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/synctestfor 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()fromgoogle/go-cmpfor 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 -coverandgo tool cover -htmlfor analysis
7. Test Fixtures
- Use
testdatadirectory 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
benchstatfor statistical analysis - Use
-benchmemfor memory profiling
10. Naming Conventions
- Test functions:
Test*,Benchmark*,Fuzz*,Example*(capital letter after prefix) - Use
gotandwantfor 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.