Testify in Go tests
Keep Go's testing package as the test runner and match the repository's existing assertion style. Use Testify where its diagnostics, suites, or mocks improve the test; a direct if remains appropriate when clearer.
Inspect before editing
Check go.mod, package-level assertion conventions, helper functions, mock-generation or hand-written mock patterns, suite usage, parallel tests, and linters such as testifylint. Verify APIs against the selected version before adopting newer assertions or mock helpers.
Assertions and requirements
- Use
requirefor a failed precondition after which continuing would panic or make later results meaningless. - Use
assertwhen independent checks can still provide useful diagnostics after one fails. - Keep expected and actual argument order correct for assertions that distinguish them.
- Use
ErrorIs/ErrorAsfor wrapped errors when identity or type matters; compare text only when text is the contract. - Testify equality assertions perform value-oriented comparison for supported values, including pointed-to data. Use identity-specific assertions when pointer identity itself is the behavior.
require ultimately calls FailNow, so call it from the goroutine running the test rather than an asynchronous worker. Communicate worker failures back to that goroutine. Make callbacks used by eventual assertions concurrency-safe and give them meaningful time bounds.
For concrete assertion selection, eventual checks, mock implementations and matchers, and suite hooks, read references/api-and-testing.md.
Choose assertions that describe the contract directly. A helper or custom assertion is worthwhile when it improves repeated failure diagnostics, not merely to hide setup or compress a one-line standard-library check.
Use t.Helper in local wrappers so failures point to the caller rather than the assertion utility.
Mocks
Mock a meaningful interaction boundary, not internal implementation details that make refactoring unnecessarily expensive. Prefer a small fake when it expresses stateful behavior more clearly.
When using testify/mock:
- match arguments narrowly enough to verify behavior without depending on irrelevant representation;
- declare call counts only when count is part of the contract;
- return values with the exact types and nil behavior expected by the mocked method;
- verify expectations using the pattern supported by the selected version and repository;
- treat call ordering as unspecified unless the test explicitly configures and requires it;
- avoid sharing mutable mock state across parallel tests without synchronization.
A broad Anything matcher can hide a missing contract. A mock panic often indicates an expectation or return-type mismatch worth diagnosing.
Suites and test isolation
Create fresh state for each test and release resources with t.Cleanup or suite teardown. Confirm the selected version and shared-state safety before running suite methods in parallel. Ensure every suite has a normal TestXxx entry point that calls suite.Run.
Verification
Run formatting, the affected tests, race detection when concurrency changed, and configured linters. Confirm failing-path diagnostics are useful: intentionally broken expectations should fail for the behavior being tested, not due to setup panic or leaked state.