Testing

Testing Go CLIs with testscript

How cmd/go's script tests led me to testscript, and how to use it for CLI tests that exercise argv, stdout, stderr, exit codes, and scratch files.

A tour of txtar

txtar is a tiny plain-text archive format Russ Cox introduced in 2018 for multi-file test fixtures. The Go Playground, cmd/go's script tests, gopls's marker tests, and rsc.io/rf all reach for it.

Testing unary gRPC services in Go

How to test unary gRPC services in Go - handler logic, interceptors, deadlines, metadata propagation, and rich error details - all in-memory with bufconn.

Your Go tests probably don't need a mocking library

Practical patterns for mocking in Go without external libraries. Learn to mock functions, methods, interfaces, HTTP calls, and time using only the standard library

Tap compare testing for service migration

Master shadow testing for large-scale system migrations. Learn to safely rewrite services by comparing outputs between old and new implementations.

Re-exec testing Go subprocesses

Test Go subprocesses with the re-exec pattern: spawn your test binary as a subprocess to emulate real command behavior reliably.

Revisiting interface segregation in Go

Apply SOLID's Interface Segregation Principle in Go with consumer-defined contracts. Learn why small interfaces and implicit implementation matter.

Organizing Go tests

Organize Go tests with in-package, external _test packages, and integration tests. Learn white-box vs black-box testing conventions.

Subtest grouping in Go

Organize Go subtests with t.Run nesting and parallel execution. Learn patterns for setup, teardown, and readable test hierarchies.

Test state, not interactions

Avoid brittle AI-generated tests that check implementation details. Write maintainable tests that verify behavior, not method calls.

Early return and goroutine leak

Prevent goroutine leaks caused by early returns with unbuffered channels. Learn buffering, draining, errgroup patterns, and goleak testing.

Lifecycle management in Go tests

Master Go test lifecycle with t.Cleanup(), subtests, and TestMain. Learn per-test, grouped, and package-wide setup patterns effectively.

Flags for discoverable test config in Go

Control Go test behavior with custom flags instead of build tags or env vars. Enable integration and snapshot tests with discoverable CLI options.

You probably don't need a DI framework

Dependency injection in Go doesn't need Dig or Wire. Learn why manual wiring beats reflection magic and how Go's design makes DI frameworks overkill.

Capturing console output in Go tests

Test functions that write to stdout/stderr in Go by capturing output with os.Pipe. Learn patterns to avoid deadlocks in concurrent tests.