go-testing-with-testify · diff
git:20260828.7779331 to git:20260904.6c1f699
126 added, 352 removed. Audit A to A.
---
name: go-testing-with-testify
- description: Use when writing, reviewing, or hardening Go tests that rely on stretchr/testify — `assert`, `require`, `mock`, and `suite` — including table-driven tests, subtests, parallel tests, mocks versus hand-written fakes, error-wrap assertions, and flaky test triage with `-race` and `-count`.
+ description: Write, review, or harden Go tests using stretchr/testify assert, require, mock, or suite. Use for assertion choice, test doubles, subtests, concurrency, and flake triage in an existing Go test setup. Use coding-guidance-go for production code or non-testify tests and tester-mindset for test strategy without concrete test code.
---
# Go Testing With Testify
- Workflow for writing, reviewing, and hardening Go tests built on the standard
- `testing` package and the `stretchr/testify` toolkit (`assert`, `require`,
- `mock`, `suite`).
-
- **Go+testify tests are checks** — automated pass/fail assertions on behavior
- contracts. **Testing as investigation** — charters, heuristics, oracles under
- stress, edge-case discovery, perspective rotation — is upstream. Compose with
- `tester-mindset` when strategy, risk framing, or the shape of the unknown
- dominates.
-
- ## When To Use
-
- - writing new Go unit, integration, or HTTP handler tests with testify
- - refactoring existing `*_test.go` files: tightening assertions, extracting
- table-driven tests, introducing subtests, or adding `t.Parallel()`
- - reviewing PRs that add or change Go tests
- - triaging a flaky Go test (intermittent, `-race` complaints, order-dependent)
- - replacing `reflect.DeepEqual` / string-match / manual error checking with
- testify assertions, or deciding when **not** to
- - deciding between a hand-written fake and `testify/mock`, or between flat
- subtests and a `suite.Suite`
- - pairing with `tester-mindset` for claims, oracles, and edge-case coverage
- - pairing with `backend-guidance` or `backend-systems-guidance` for service-
- boundary test design in Go services
-
- ## Not For
-
- - standing up a Go module or repo-level test tooling from scratch — that is a
- one-off install step (`go mod init`, `go get github.com/stretchr/testify`)
- not a skill-shaped workflow
- - strategy work without any testify or `testing` code in the loop — that is a
- `tester-mindset` job
- - pure code-style review of non-test Go code — this skill should not be
- primary; use the repo's implementation or review skill set instead,
- typically `backend-guidance` or `backend-systems-guidance` for Go services
- - Ginkgo, Gomega, `go-cmp`-only, or gocheck suites — the testify idioms below
- will fight those stacks
-
- ## Routing Flowchart
-
- ```dot
- digraph route {
- "Main artifact is testify-based Go test code or test review?" [shape=diamond];
- "Main artifact is strategy,\nedge-case discovery, or test planning\nwithout concrete test code?" [shape=diamond];
- "go-testing-with-testify" [shape=box];
- "tester-mindset" [shape=box];
- "coding-guidance-go or another repo skill set" [shape=box];
-
- "Main artifact is testify-based Go test code or test review?" -> "go-testing-with-testify" [label="yes"];
- "Main artifact is testify-based Go test code or test review?" -> "Main artifact is strategy,\nedge-case discovery, or test planning\nwithout concrete test code?" [label="no"];
- "Main artifact is strategy,\nedge-case discovery, or test planning\nwithout concrete test code?" -> "tester-mindset" [label="yes"];
- "Main artifact is strategy,\nedge-case discovery, or test planning\nwithout concrete test code?" -> "coding-guidance-go or another repo skill set" [label="no"];
- }
- ```
-
- ## Adjacent Skills
-
- - **upstream strategy:** `tester-mindset` for claims, oracles, consequence
- framing, and stopping rules
- - **Go implementation:** `coding-guidance-go` for production Go code, package
- design, errors, context, concurrency, and review
- - **service boundaries:** `backend-guidance` (baseline) or
- `backend-systems-guidance` (non-trivial boundaries, repositories, queues)
- for what to test at which seam
- - **security-led test work:** add `security` only when exploit analysis, threat
- modeling, or secure-default judgment is part of the job; add
- `security-identity-access` with it for authentication, sessions, recovery,
- federation or account linking, identity callbacks, invitations, or tenant
- authorization. For routine testify implementation of an already-defined
- security requirement, keep this skill primary.
- - **config and deterministic fixtures:** `project-config-and-tests` for
- config contracts, path helpers, and deterministic data
- - **documentation of testing conventions:** `documenter` for repo-level
- `TESTING.md` or contributor guides
-
- Many Go testing tasks are just this skill plus `tester-mindset` when the claim
- or edge-case framing still needs work. Add a backend overlay only when the seam
- is actually a handler, repository, queue, or cross-service boundary.
- For non-test Go implementation or review, start with `coding-guidance-go` and
- add this skill only when testify-based tests are the main artifact.
-
- ## Reference Map
-
- - [references/assertion-patterns.md](references/assertion-patterns.md) —
- `assert` vs `require`, equality variants, error-wrap assertions, async
- readiness helpers
- - [references/mocking-patterns.md](references/mocking-patterns.md) —
- hand-written fakes, `testify/mock`, ownership rules, argument matching,
- optional calls, and order constraints
- - [references/real-boundary-patterns.md](references/real-boundary-patterns.md)
- — cheapest-honest-boundary defaults for HTTP, repository, filesystem,
- clocks, and async seams before reaching for mocks
- - [references/suite-and-parallelism.md](references/suite-and-parallelism.md) —
- `suite.Suite` tradeoffs, subtests, `t.Parallel()`, `t.Setenv`,
- `t.TempDir`, `t.Cleanup`, `t.Context`, deterministic ordering
- - [references/pressure-tests.md](references/pressure-tests.md) —
- maintainer-only RED/GREEN scenarios
- - [references/coverage-and-validation.md](references/coverage-and-validation.md)
- — maintainer-only doc coverage audit and routing checks
-
- Load reference files on demand; do not read the entire folder up front.
-
- ## Core Workflow
-
- 1. **Map the claim and the seam.** Before touching `*_test.go`, name the
- behavior claim in one falsifiable sentence, the relevant stakeholders, and
- the cost of being wrong. Pick the seam: pure function, package API, HTTP
- handler, repository, or cross-service integration. The seam decides whether
- a table-driven unit test, a `httptest.Server`-backed integration test, or
- a `-tags=integration` test against a real dependency is the right
- consequence to invite.
- 2. **Prefer the smallest real boundary.** Pure logic → unit test. Anything
- touching a DB, queue, HTTP server, filesystem, or clock → use the real
- thing when it is cheap (`testcontainers-go`, `httptest.NewServer`,
- `t.TempDir()`, `context.WithCancel`) before reaching for a mock. Mocks
- belong at owned interface seams you control, not at the SUT. See
- `references/real-boundary-patterns.md` for concrete harness shapes.
- 3. **Write table-driven subtests by default.** Name each row with a meaningful
- string, run it via `t.Run(tc.name, func(t *testing.T) { … })`, and use
- `t.Parallel()` deliberately — not reflexively. See
- `references/suite-and-parallelism.md` for the parallelism checklist.
- 4. **Choose `require` vs `assert` per line, not per file.** `require.*` halts
- the test on failure; use it for preconditions whose failure would make the
- rest of the test meaningless (setup, `err` from the action under test when
- subsequent asserts read the return value). `assert.*` continues; use it
- for independent output checks so one failing row does not hide the others.
- 5. **Use specific assertions over generic ones.** Prefer
- `assert.ErrorIs(t, err, ErrNotFound)` over `assert.Error` plus string
- matching; `assert.ElementsMatch` over sorting-then-Equal when order is
- incidental; `assert.JSONEq` over byte-for-byte string equality on JSON.
- See `references/assertion-patterns.md` for the full menu.
- 6. **Inject the ambient dependencies you assert on.** Clock, randomness, IDs,
- HTTP client, and environment are the usual flake sources. If a test needs
- `time.Now()` to land in a specific window, the code has a design tap —
- inject a `Clock` interface or pass the timestamp as a parameter.
- Hard-to-test behavior is design feedback; refactor the seam before wrapping
- it in sleeps or retries.
- 7. **Run `-race -count=N` before declaring a test stable.** At least
- `go test -race -count=10 ./…` on changed packages; more when the test
- touches concurrency. A single green run proves almost nothing about
- parallel tests.
- 8. **Name what this test does not cover.** Narrow the conclusion: which
- inputs, which failure modes, which environments, which timings were left
- out. This becomes the input to the next consequence — integration test,
- fuzz target, property test, chaos probe, or monitoring — if risk remains.
-
- ## Preflight
-
- Before rewriting or approving testify-based tests:
-
- 1. Confirm the target package, module path, and exact `*_test.go` files in
- scope. Prefer narrow package targets over `./...` while iterating.
- 2. Read `go.mod` and the existing neighboring tests first. The module's Go
- version changes what loop-variable capture and `testing.T` helpers are
- available.
- 3. Confirm whether the repo already uses testify and in what shape:
- plain `assert`/`require`, `mock`, `suite`, `assert.New(t)`, or a local
- helper layer.
- 4. Start with a narrow command such as
- `go test ./path/to/pkg -run '^TestName$' -count=1`, then harden later with
- `-race`, higher `-count`, or `-shuffle=on` as the claim requires.
- 5. If the repo already runs `golangci-lint` with `testifylint`, preserve or
- satisfy it. Testify's own README recommends `testifylint` to avoid common
- mistakes.
-
- ## Testing Vs Checking
-
- The testify API is almost entirely a **checking** toolkit: automated
- pass/fail rules on known expectations. That is valuable and not in tension
- with `tester-mindset` — unless agents mistake passing checks for having
- tested. Before writing or approving a test, name the claim, the oracle, and
- what the test cannot disprove. Passing assertions reduce uncertainty; they
- do not convert partial coverage into certainty.
-
- ## Assertion Rules
-
- Heuristics, not laws. Treat them as fallible lenses that fit most cases; name
- the context when you break them.
-
- - **Argument order:** `assert.Equal(t, expected, actual)`. Swapping flips
- failure messages and trains readers to distrust the diff. Same for
- `NotEqual`, `ElementsMatch`, `InDelta`.
- - **Errors:** use `assert.ErrorIs` / `assert.ErrorAs` for sentinel and
- typed-error checks. Reserve `assert.EqualError` / string matching for
- messages that are part of the public contract (CLI output, API error
- body). Never assert on wrapped error text that the stdlib or a dependency
- can reword.
- - **Happy path + at least one failing branch.** A test that only covers the
- success path is a check that the code compiles under ideal input.
- - **Avoid `assert.NotNil` / `assert.True` as primary oracles** when a
- stronger assertion exists. `require.NoError(t, err); assert.Equal(t, want,
- got.Field)` beats `assert.NotNil(t, got)`.
- - **Do not assert on fields the test did not set.** It is a common drift
- source: a struct literal with six fields, test asserts on all six via
- `Equal`, an unrelated field is added, every test breaks. Compare only the
- fields whose behavior the test claims.
- - **`t.Helper()` in every helper.** Without it, failure messages point at
- the helper line, not the test line. Non-negotiable for shared setup and
- assertion wrappers.
- - **Readiness over sleeps.** For async state, use `assert.Eventually` /
- `require.Eventually` with a tight tick, an injected clock, or a channel.
- Never `time.Sleep` in a test outside of an explicit reason documented
- inline.
- - **`require.*` stays on the test goroutine.** `require` terminates the current
- test via `t.FailNow()`. Do not call it from helper goroutines spawned by the
- test.
-
- ## Mock vs Fake
-
- - **Fake first** for narrow, owned interfaces (3–5 methods). A 40-line
- hand-written struct that implements the interface is clearer than a mock
- setup block, and it survives refactors better because the compiler checks it.
- - **`testify/mock`** earns its keep for wide interfaces, call-order
- assertions, or when the test genuinely needs to verify the arguments a
- collaborator was called with. Always `mock.AssertExpectations(t)` at the
- end so missing calls fail the test.
- - **Mock only what you own.** Wrap third-party APIs in an interface you own
- and fake that. Direct mocks of third-party types are brittle and rot on
- every dependency bump.
- - **Never mock the system under test.** If a test needs to mock a method on
- the type it is testing, the test is asserting on the mock, not the code.
- Split the type or flip the dependency.
- - **Prefer `httptest.NewServer` over mocking an HTTP client.** For code that
- speaks HTTP, a real server with handlers the test controls is usually the
- cheapest real boundary.
-
- See `references/mocking-patterns.md` for the full rules and concrete
- examples.
-
- ## Subtests And Parallelism
+ Turn a concrete behavior claim into useful Go test evidence. Preserve the
+ repository's Go version, test framework, and supported execution environment.
- - Table-driven + `t.Run(tc.name, …)` is the default. One test, one row's
- concern. Named rows mean the `-run TestFoo/specific_case` flag works for
- local triage.
- - `t.Parallel()` is a claim that the test shares no hidden state with its
- siblings. Before adding it, check for: package-level globals, shared temp
- dirs, a shared DB schema, `os.Setenv`, and time-of-day assumptions.
- - Loop-variable capture: on Go ≥ 1.22 the per-iteration variable is per-row
- by default, so `tc := tc` is no longer required. On older modules, keep
- the rebind. Either way, prefer the explicit rebind in shared review
- templates — it is invariant across versions.
- - `suite.Suite` is familiar to xUnit refugees but discourages parallelism
- (the shared receiver is not safe for `t.Parallel()`) and hides setup/state
- behind `SetupTest`/`TearDownTest`. Use it for a coherent scenario group
- that truly shares setup cost; reach for flat subtests otherwise. See
- `references/suite-and-parallelism.md`.
+ ## Route And Select Activity
- ## Flake Triage
+ - **Implement or harden:** edit the requested tests and any explicitly covered
+ production seam. A test request does not automatically authorize an unrelated
+ production refactor, new dependency, or external service.
+ - **Review:** inspect tests and report prioritized findings, evidence, and
+ consequences. Do not edit files or require remediation to complete a review.
+ - **Diagnose:** reproduce the named failure in scope, distinguish a product
+ defect from a test-apparatus defect, then fix it when the request includes repair.
- When a test is flaky, treat the flake as a signal, not a nuisance.
+ Use `coding-guidance-go` for production Go or non-testify tests. Preserve
+ Ginkgo, Gomega, go-cmp-only, and other intentional stacks. Module bootstrap or
+ test-tool installation is separate from test authoring.
- 1. **Reproduce.** `go test -race -count=100 -run TestFoo ./pkg/...`. Add
- `-parallel=4` or `-parallel=1` to see if concurrency is the vector.
- 2. **Inspect the apparatus.** Is the test asserting on a timestamp, a map
- iteration order, a goroutine scheduling order, or a shared temp dir?
- Those are the usual offenders.
- 3. **Look for the race.** Every `-race` complaint is a real bug, not test
- flake. Fix the code or the test, never suppress.
- 4. **Sleeps are not a fix.** Replace with `assert.Eventually`, an injected
- clock, a synchronization primitive (`sync.WaitGroup`, channel), or a
- `context.WithTimeout` that the test can cancel.
- 5. **Order dependence.** If `go test -shuffle=on` fails, the test relies on
- run order. Fix the shared state, don't freeze the order.
- 6. **Only then consider quarantine.** `t.Skip` with a linked issue and a
- date-bounded expiry is acceptable for a failure the team cannot fix this
- sprint; `t.Skip` without either is hiding a bug.
+ Add `tester-mindset` when claims, oracles, or test strategy are still unclear.
+ Add `backend-guidance` or `backend-systems-guidance` only when a service,
+ repository, queue, or other backend boundary needs that design guidance.
+ Use `security` first for a security-led review and add
+ `security-identity-access` when its identity scope applies. Routine tests of an
+ already-defined permission rule can remain here.
- ## Failure-Class Triage
+ ## Workflow
- Before blaming the production code, rule out the usual test-apparatus bugs:
+ 1. Read the scoped tests, implementation, `go.mod`, fixtures, and relevant
+ repository instructions. Identify the Go and testify versions, local test
+ command, helpers, and available dependencies.
+ 2. Name the behavior claim, oracle, and smallest seam that can reveal a defect.
+ Pure logic needs a unit check; protocol, query, serialization, or lifecycle
+ behavior may need a real boundary. Passing checks support only their scope.
+ 3. Preserve the existing test shape when it is clear. Use table-driven subtests
+ when cases share setup and assertions; use separate tests when they do not.
+ Introduce helpers, fakes, mocks, or suites only for a concrete benefit.
+ 4. For implementation, exercise the real code and assert the behavior being
+ claimed. For review, assess these choices without rewriting the tests.
+ 5. Validate the narrowest changed test or package, for example
+ `go test ./path/to/pkg -run '^TestName$' -count=1`. Add race checks,
+ repetition, shuffle, or integration runs when the failure mode needs them.
+ 6. Inspect failures before changing assertions, retry counts, or timeouts.
+ Report the exact evidence and remaining uncertainty.
- - `-race` failures: a real data race in the code or the test
- - shared process state: `t.Setenv`, current working directory, or package
- globals used under `t.Parallel()`
- - shared temp paths or ports instead of `t.TempDir()` and unique listeners
- - map iteration order, `time.Now()`, `rand`, UUID generation, or goroutine
- scheduling used as if deterministic
- - Go-version assumptions: older modules still need explicit loop-variable
- rebinding in parallel table tests; newer ones may expose stale review lore
- - stale local cache assumptions while iterating: use `-count=1` during rapid
- diagnosis, then broaden again for stability checks
+ ## Assertions And Oracles
- These are apparatus bugs, not proof the behavior contract is wrong.
+ - Put expected before actual in testify comparisons.
+ - Use `require` for prerequisites whose failure makes later checks unsafe or
+ meaningless; use `assert` for independent checks. A fatal failure in a
+ subtest stops that subtest, not its siblings.
+ - Call `require.*`, `t.Fatal`, and `t.FailNow` only on the test goroutine.
+ Return observations or errors from HTTP handlers and workers through a
+ synchronized channel or result, then assert on the test goroutine.
+ - Use `ErrorIs` or `ErrorAs` when error identity or type is the contract.
+ Error presence alone is sufficient when that is all the contract promises.
+ Assert text only when it is intended to be stable.
+ - Use equality, unordered comparison, identity, structural JSON, or tolerances
+ according to the contract. Exact float equality is valid for exact expected
+ values; approximate computations need justified tolerances.
+ - Check fields the behavior promises, including generated IDs, defaults, or
+ timestamps when relevant. Whole-struct equality is valid when the full value
+ is the contract; do not discard meaningful fields merely to avoid failures.
+ - A success-only test can be meaningful. Add separate failure cases where they
+ protect required behavior; do not require every individual test to exercise
+ both success and failure.
+ - Call `t.Helper()` in helpers whose failures should identify their caller.
- ## Stopping Rule
+ Reject tautologies, mocks that replace the behavior being proved, and assertions
+ that cannot detect a plausible defect in the stated claim. A no-error assertion
+ can prove a narrow validation contract but does not prove that a user was stored
+ or a file's contents are correct. Logs can be the oracle when logging itself is
+ the requested behavior.
- Stop adding tests when the claim has risk-appropriate evidence, remaining
- uncertainty is named, and the next test would cost more than the confidence
- it could add. If material risk remains but more unit tests are inefficient,
- shift to integration tests, fuzzing, property tests, load probes, monitoring,
- or staged rollout. Coverage percent is a weak oracle; the tester-mindset
- stopping rule beats a number.
+ ## Boundary And Double Choice
- ## Weak Test Detector
+ Prefer an existing cheap real harness when the risk is at that boundary:
- Reject tests that cannot meaningfully fail for the right reason.
+ - HTTP protocol behavior: `httptest.NewServer`;
+ - filesystem behavior: `t.TempDir()`;
+ - database queries or transactions: a disposable dialect-appropriate harness;
+ - time or async behavior: explicit synchronization, injected time, or supported
+ virtual-time testing.
- Forbidden patterns:
+ Use a fake for a simple owned collaborator; use `testify/mock` when argument,
+ call-count, failure, or ordering expectations improve the test. Respect existing
+ test seams. Do not introduce wrappers or containers solely to satisfy a generic
+ mock rule, and do not contact live or metered services without authority.
- - `assert.True(t, true)`, `assert.Equal(t, x, x)`, and any assertion whose
- operands are both computed from the same source.
- - Schema-only assertions: `assert.NotNil(t, resp); assert.NoError(t, err)`
- with no check on the value the function returns.
- - Tests that call `require.NoError(t, err)` on the action under test and
- then assert nothing else. The function ran; that is not a behavior claim.
- - Mocking the SUT (see above).
- - Asserting on log output as the primary oracle when a return value or
- stored state exists. Logs are a side channel, not a contract.
- - `assert.Contains(t, err.Error(), "not found")` when `errors.Is(err,
- ErrNotFound)` would work. String-match on errors that are not part of the
- public contract is a brittleness trap.
- - Tests whose fixture is a literal that the test then reads back: a
- roundtrip through a mock that the test itself configured proves the mock,
- not the code.
- - `t.Skip("flaky")` without an issue link and an expiry.
+ Wire the double into the subject under test. Assert mock expectations after
+ owned asynchronous calls finish, using cleanup when it must also run after a
+ fatal test failure. Keep matchers specific to the promised interaction and
+ avoid retaining mutable pointer arguments as if they were immutable snapshots.
- Self-verify after writing: if I corrupted the production behavior in the
- simplest plausible way, would this test fail? If not, the test is proof
- theater.
+ ## Concurrency, Time, And Cleanup
- ## Rationalization Table
+ - Add `t.Parallel()` only after checking shared state, database schemas, ports,
+ temporary paths, environment, current directory, and goroutine lifetimes.
+ `t.Setenv` and `t.Chdir` cannot be used in parallel tests or with parallel
+ ancestors; check helper availability against the supported Go version.
+ - Testify `suite` does not support parallel tests. Keep suites when their
+ scenario and lifecycle organization helps; do not migrate them for style alone.
+ - Go 1.22+ loop semantics depend on the module language version. Rebind loop
+ variables where older semantics require it, not as mandatory modern boilerplate.
+ - Register cleanup next to acquisition. Own cancellation and wait for workers
+ before test teardown; a deadline limits waiting but does not itself join work.
+ `t.Context()` is available from Go 1.24 and cancels before cleanup.
+ - Prefer completion signals to polling. Use bounded `Eventually` only for a
+ genuinely eventual observable state and synchronize shared reads.
+ - On Go 1.25+, consider `testing/synctest` for compatible in-process concurrent
+ code. Virtual time is not a replacement for real network or external-system
+ evidence. Sleeps inside its virtual-time bubble differ from wall-clock delays.
+ - Keep each operation's timeout and cleanup bounded. A slow polling callback can
+ outlive the assertion budget if its own I/O has no cancellation.
- Pressure excuses belong in
- [references/pressure-tests.md](references/pressure-tests.md). Use that
- reference when revising this skill, reviewing a contentious test change, or
- checking whether a proposed shortcut weakens evidence.
+ ## Flake Triage And Completion
- ## Output Shape
+ Reproduce one failing test with its original environment, then vary a relevant
+ dimension: ordering, workers, parallelism, timing, or shared state. Use
+ `-race` for suspected races and `-count=N` or `-shuffle=on` for repetition
+ and order dependence; choose the package and run budget from the risk.
+ A finite passing sample does not prove that a flake is impossible.
- When recommending or delivering tests, include:
+ Distinguish a data race, product defect, fixture bug, resource leak, unsupported
+ runtime, and external dependency failure. Fix causes without weakening the
+ oracle. Quarantine only under the repo's accepted policy with a reason, owner,
+ tracking reference, and revisit condition.
- - **Claim:** behavior or failure mode being tested
- - **Seam:** pure function, package API, handler, repository, external client
- - **Cases:** rows, subtests, or scenarios implemented or proposed
- - **Oracles:** assertions or observable effects that define failure
- - **Evidence:** commands run, flags used, and result
- - **Residual risk:** what passing still does not prove
+ Stop when the changed claim has proportionate evidence and further similar
+ tests would add little confidence. Report material untested behavior and the
+ next useful check. A completed review may contain unresolved findings.
- ## Examples
+ Return the claim, seam, cases, oracles, exact commands/results, and residual risk
+ when they help assess the work; collapse these into a short note for a small edit.
- - *"Write tests for this new `UserService.Register` method."* → map claim +
- stakeholders + cost, seam = package API, table-driven subtests for
- validation failure modes, one `httptest.NewServer` integration for the
- mailer boundary, `ErrorIs` on sentinel errors; pair with
- `backend-guidance` for handler-side wiring.
- - *"Write tests for this parser package."* → seam = package API, table-driven
- rows for malformed input, normalization edge cases, and wrapped parse
- errors; `assert.ErrorIs` for sentinels, no backend overlay needed.
- - *"This test passes locally but fails in CI."* → run flake triage:
- `-race -count=100`, inspect fixture (temp dirs, env, timezone), check
- `-shuffle=on`, look at `-parallel`; propose injected clock or
- `Eventually` if the failure is timing-bound.
- - *"Convert this `suite.Suite` to flat subtests."* → check whether shared
- setup is cheap enough to recreate per row; migrate to table-driven with a
- `newTestEnv(t)` helper; confirm each row can `t.Parallel()` after an
- explicit shared-state audit.
- - *"Replace these brittle mocks with something better."* → identify the
- seam, check if the interface is owned and narrow (fake) vs wide or
- third-party (mock-with-own-wrapper); for HTTP, prefer
- `httptest.NewServer`.
- - *"Edge cases for this JSON marshaler."* → compose with `tester-mindset`
- first for charters and heuristics; return here to encode them as
- `assert.JSONEq` rows.
+ ## References
- ## Maintainer Notes
+ Load only the detail relevant to the task:
- - Keep reference files load-on-demand. Do not pull them into the skill
- body.
- - When testify or Go releases a feature that changes test idioms (e.g., Go
- loop-variable semantics in 1.22, new `testing.TB` helpers, testify
- assertions), update the affected reference and add a pressure-test row
- if it closes a rationalization.
- - Pressure tests in `references/pressure-tests.md` are the verification
- harness for this skill. Run a representative subset before any
- substantive rewrite.
+ - [Assertion patterns](references/assertion-patterns.md): equality, errors,
+ async assertions, and helpers.
+ - [Mocking patterns](references/mocking-patterns.md): fakes, expectations,
+ argument matching, pointer mutation, and ordering.
+ - [Real boundaries](references/real-boundary-patterns.md): HTTP, database,
+ filesystem, clocks, and worker lifecycle examples.
+ - [Suites and parallelism](references/suite-and-parallelism.md): lifecycle,
+ subtests, Go-version constraints, and process-wide state.
+ - [Pressure scenarios](references/pressure-tests.md): maintainer or contentious
+ review cases; distinguish static assessment from observed behavior.
+ - [Coverage and validation](references/coverage-and-validation.md): maintainer
+ source map, routing boundaries, and evidence limitations.