How would you separate integration tests from unit tests using build tags? What alternatives exist?
Question 424MediumGo 1.22 to 1.25
Put a custom tag on the integration test files, then opt in when running tests:
//go:build integration
package store_test
import "testing"
func TestPostgresRoundTrip(t *testing.T) {
dsn := mustEnv(t, "TEST_DSN")
// ... real database
_ = dsn
}
// run:
// go test ./... // unit only
// go test -tags=integration ./... // include integration
Gotchas:
- gopls and go vet don't see tagged files unless configured (
"buildFlags": ["-tags=integration"]), so the files can rot without anyone noticing. - If every file in a package is tagged, an untagged build reports "build constraints exclude all Go files".
- Test caching depends on the tag set, which is correct behavior.
Alternatives interviewers like to hear about:
testing.Short()withgo test -shortto skip slow tests.- Skipping when an environment variable is missing (
t.Skip). The code is always compiled, so it cannot rot. - Separate
TestMainsetup using testcontainers. - Running by name with
-run 'Integration'.
A senior answer: prefer env-based skipping so the code stays compiled and type-checked, and use tags only when the tests import heavy dependencies you want kept out of normal builds.
More on Modules, Packages & Tooling
- Q422What is the difference between go get and go install pkg@version in module mode?
- Q423Explain build constraints: the //go:build syntax, filename rules, and common gotchas.
- Q425How does go generate work, and what are best practices around it?
- Q426What are the tradeoffs of using cgo? When would you avoid it?
- Q427What are the cgo pointer-passing rules, and how does runtime.Pinner help?
- Q428How do you cross-compile Go and produce a fully static binary for a scratch container?