بنقرة واحدة
integration
Integration tests — real database, build tags, transaction isolation.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Integration tests — real database, build tags, transaction isolation.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Visual-design discipline for forge frontends — brief the work before building (never invent an aesthetic without user input), declare the design system before coding, lean on the component library, use restrained color/type systems, never hand-draw complex SVGs, and verify visually before declaring done.
Write Next.js frontends — generated hooks, component library, Tailwind v4, visual verification, and Connect RPC clients.
Outbound boundary translators. One adapter per third-party system / queue / storage backend; narrow interface, vendor-neutral callers.
Write Connect RPC handlers — proto-driven codegen, the thin-translation handler pattern (validate, extract auth, convert proto↔internal, call service, wrap errors via `svcerr.Wrap`), middleware, and testing. Business logic lives in `internal/handlers/<svc>/contract.go`, never in handlers.
Forge project conventions and architecture — project structure, generated vs hand-written code, the generate pipeline, proto annotations, contracts, wiring, and naming.
Use-case orchestrators that compose two or more adapters/services. Deps are interfaces only — designed for unit tests with all-mock collaborators.
| name | integration |
| description | Integration tests — real database, build tags, transaction isolation. |
Integration tests run against a real database and verify that queries, migrations, and data access layers work correctly. They are invisible to plain go test because they require a build tag.
Every integration test file must include the build constraint at the top:
//go:build integration
package handlers_test
This keeps them out of go test ./... and ensures they only run when explicitly requested.
testing.Short()Forge integration tests use the //go:build integration build tag — not testing.Short() with t.Skip(...). The two mechanisms answer different questions:
| Mechanism | What it does | Use when |
|---|---|---|
//go:build integration | The Go toolchain physically excludes the file from go build / go test unless -tags integration is passed. No compile, no link, no skip-at-runtime. | The test needs infra that may not be present (DB, broker, network). The default test run must not even attempt it. |
if testing.Short() { t.Skip(...) } | The test is always compiled and runs by default. go test -short skips it at runtime. | The test is hermetic but optionally slow — e.g. a fast unit test that has an extra long-running scenario behind -short. |
Rule for forge projects: all DB-backed / RPC-roundtrip / infra-dependent tests use the build tag. Reserve testing.Short() for the rare case of a hermetic test with a fast/slow toggle. If your test would t.Skip because it can't reach a database, it belongs behind //go:build integration instead.
The matching convention for end-to-end tests is //go:build e2e.
forge test integration # runs all integration tests
forge test integration --service <name> # one service only
forge test --coverage # includes integration in coverage
The forge test integration command automatically adds -tags integration to the Go test invocation.
Integration tests require a running Postgres instance via docker-compose. If you're already running the stack, you're set:
forge up --env=dev # starts the full stack including postgres
pkg/testkit ships the harness pieces an integration test needs — a migrated test DB, authed contexts, claims options — and pkg/tdd exposes table-driven entry points on top (tdd.SetupMockDB, app.NewMigratedTestDB). Reach for those before hand-rolling connection + migration boilerplate. See the testing and testing/patterns skills for the cheat sheet.
Mock discipline at this tier: the subject and its real internal collaborators (including the DB) stay real — that's the whole point of integration. Mock only third-party boundaries you don't own.
Each test runs inside a database transaction that is rolled back in cleanup. This guarantees complete state isolation between tests:
func TestCreateUser(t *testing.T) {
tx := testdb.Begin(t) // starts transaction
t.Cleanup(func() { tx.Rollback() })
queries := db.New(tx)
// ... test with real queries
}
Integration tests are the right place to verify sqlc-generated queries against the real schema. Test the actual SQL — don't mock the database when the query behavior is what you're validating.
t.Cleanup() (transaction rollback handles this automatically)