数据库安装
- 作者仓库星标 0
- 作者更新于 实时读取
- 作者仓库 skills-registry
- 领域
- AI 智能
- 兼容 Agent
-
- Claude Code
- Cursor
- Cline
- Codex
- Windsurf
- Gemini CLI
- +20
- 信任分
- 88 / 100 · 社区维护
- 作者 / 版本 / 许可
- @tomevault-io · 未声明 license
- Token 消耗评级
- 低消耗
- 接入复杂程度
- 需手动接入
- 是否需要外部 API Key
- 不需要
- 兼容的系统
- Linux · Docker
- 底层运行要求
- Docker
- 文件与系统权限
-
- 只读
- 允许写入 / 修改
- 读取环境变量
- 网络行为
- 仅限本地
- 安装命令数
- 26 条
档案由构建时根据 SKILL.md 与安装命令自动衍生,可能与作者实际意图存在差异。
需要注意: 未限定 allowed-tools,默认拥有全部工具权限。
---
name: golang-testcontainers
description: Write Go integration tests with testcontainers-go Use when this capability is needed. Use this s…
category: AI 智能
runtime: Docker
---
# golang-testcontainers 输出预览
## PART A: 任务判断
- 适用问题:提示词、Agent 工作流、模型评估或自动化推理。
- 输入要求:目标材料、限制条件、期望输出和验收方式。
- 证据边界:围绕“When to Use / Default Stance / Terminology: Containers Are Not Mocks”读取原文规则,不把推断写成作者承诺。
## PART B: 执行结果
- **01** 任务判断:确认你的需求是否属于提示词、Agent 工作流、模型评估或自动化推理,并标出输入、限制和预期结果。
- **02** 执行计划:优先按“When to Use / Default Stance / Terminology: Containers Are Not Mocks”拆成步骤,说明每一步会读取什么、修改什么、产出什么。
- **03** 交付结果:给出可复制的命令、文件改动、检查清单或内容草稿,并说明如何继续迭代。
- **04** 风险边界:结合 读取文件、写入/修改文件、读取环境变量、主要在本地完成、通常不需要额外 API Key 给出执行前确认项。
## Running Rules
- 读取文件、写入/修改文件、读取环境变量;主要在本地完成;通常不需要额外 API Key。
- 先小样例验证,再放大到真实任务。
- 交付时同时给结果、检查口径和下一步迭代建议。 原文没有稳定的斜杠命令要求。安装验证后通常全局生效,直接在对话里点名这个 Skill 并描述任务即可。
告诉 Agent 目标文件或材料、期望结果、不可改范围、是否允许联网或执行命令。本 Skill 的权限画像是:读取文件、写入/修改文件、读取环境变量。
先用一个小任务确认它会围绕“When to Use / Default Stance / Terminology: Containers Are Not Mocks”工作;涉及文件或命令时,先看 diff、日志、预览或测试结果。
检查最终产物是否包含明确结果、必要证据和下一步动作;如果输出泛泛而谈,就补充输入、边界和验收标准后重跑。
---
name: golang-testcontainers
description: Write Go integration tests with testcontainers-go Use when this capability is needed. Use this s…
category: AI 智能
source: tomevault-io/skills-registry
---
# golang-testcontainers
## 什么时候使用
- 用于审阅代码、文档或方案并给出可执行反馈 适合处理AI Agent、提示词、模型评估与自动化推理,核心价值是把输入、判断、执行、验证和交付边界固定下来,避免 Agent 泛泛回答。 把任务拆成可执行、可检查、可继续迭代的步骤;通常不需要…
- 面向提示词、Agent 工作流、模型评估或自动化推理,优先处理能明确输入、步骤和验收标准的工作。
## 需要提供什么
- 目标材料、目录范围、期望结果和不可改动内容。
- 是否允许联网、执行命令、读写文件或调用外部服务。
## 执行规则
- 围绕「When to Use / Default Stance / Terminology: Containers Are Not Mocks」组织步骤,不把推断写成作者事实。
- 读取文件、写入/修改文件、读取环境变量;主要在本地完成;通常不需要额外 API Key。
- 先跑小样例,确认结果可检查后再扩大任务范围。
## 输出要求
- 给出最终产物、关键证据、验证方式和下一步动作。
- 信息不足时标记 unknown,不编造命令、平台或依赖。 作者原文负责流程事实;仓库文件负责来源和命令;流狐只补充适用场景、限制和质量判断。
skill "golang-testcontainers" {
输入层 -> 用户目标 + 目标文件 + 禁止范围 + 验收标准
上下文层 -> When to Use / Default Stance / Terminology: Containers Are Not Mocks
规则层 -> SKILL.md 触发条件 / 执行顺序 / 输出格式
运行层 -> Docker | 读取文件、写入/修改文件、读取环境变量 | 主要在本地完成
安全层 -> 通常不需要额外 API Key + 小任务验证 + diff / 日志复核
输出层 -> 可复制结果 + 检查清单 + 下一步迭代
} Golang Testcontainers
Use this skill when writing or reviewing Go integration tests that need real infrastructure dependencies in Docker.
Use it together with golang-testing for general Go test structure, t.Parallel() defaults, black-box package guidance, and assertion style.
When to Use
- Testing against a real Postgres, Redis, Kafka, NATS, or other containerised dependency
- Verifying SQL, migrations, indexes, transactions, locking, or driver behaviour
- Testing cache integration against a real Redis instance
- Replacing brittle fake environments with hermetic container-based integration tests
- Designing package-scoped test infrastructure that still allows parallel tests
Default Stance
Unless there is a clear reason not to, prefer these defaults:
- Use real containers for integration tests, not mocks
- Prefer module-specific helpers like
postgres.Runandredis.Runover lower-level generic setup when a module exists - Prefer
testcontainers.Runover olderGenericContainerpatterns for generic services - Register cleanup immediately with
testcontainers.CleanupContainer(t, ctr)in normal tests - For expensive services like Postgres and Redis, prefer one container per package/test binary, not one container per test
- Keep tests parallel by isolating state inside the shared container per test
- Use per-test transactions, schemas, databases, logical Redis DBs, or key prefixes instead of sharing mutable state
- Let Docker assign random host ports; do not hardcode host ports in tests
- Configure wait strategies explicitly when readiness is not guaranteed by the module
- Avoid cross-test and cross-package reuse by default; keep tests hermetic and self-contained
Terminology: Containers Are Not Mocks
For Postgres and Redis integration tests, prefer real Postgres and Redis containers.
These are not mocks.
- Mocks/fakes are best for unit tests and narrow seams
- Testcontainers are best when you want confidence in the real dependency behaviour
If the test is meant to validate SQL, migrations, transactions, Redis commands, TTL behaviour, or networked dependency behaviour, a real container is usually the right tool.
Version and API Notes
github.com/testcontainers/testcontainers-gois the main library- Prefer modern
Run(...)APIs GenericContaineris the older style; prefertestcontainers.Run(...)for new generic-container examples- Module-level
RunContainer(ctx, opts...)helpers are deprecated; preferpostgres.Run(...),redis.Run(...), etc. WithReuseByName(...)is experimental; do not make it your default CI/test strategy
Lifecycle Scope Tradeoffs
Choose container lifetime deliberately:
| Scope | Startup cost | Isolation | Parallel friendliness | Recommended use |
|---|---|---|---|---|
| Per test | Highest | Strongest | Excellent | Small suites, destructive tests, tests that mutate process-wide server state |
| Per package | Moderate | Strong if you isolate test data | Excellent when state is isolated correctly | Default for Postgres, Redis, and similar services |
| Cross-package/shared reusable container | Lowest warm-start cost | Weakest | Risky | Local experimentation only; avoid as the default |
Recommended Default
For Postgres and Redis, prefer:
- one container per package/test binary
- parallel tests inside that package
- per-test state isolation inside the container
Why this is the usual sweet spot:
- Starting one Postgres/Redis container per test is often too slow
- Sharing one container per package keeps startup cost acceptable
go testruns each package in a separate process, so package-scoped fixtures already isolate one package from another- You still need to isolate state between tests inside that package
If most tests in the package need the dependency, TestMain is a good fit. If only some tests need it, a lazy package-scoped helper can be better.
Generic Container Startup
Use generic startup when there is no higher-level module or when you need custom behaviour.
package cache_test
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
func TestWithGenericRedis(t *testing.T) {
t.Parallel()
ctx := context.Background()
ctr, err := testcontainers.Run(ctx,
"redis:7",
testcontainers.WithExposedPorts("6379/tcp"),
testcontainers.WithWaitStrategy(
wait.ForListeningPort("6379/tcp"),
wait.ForLog("Ready to accept connections").WithStartupTimeout(30*time.Second),
),
)
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)
endpoint, err := ctr.Endpoint(ctx, "")
require.NoError(t, err)
_ = endpoint // pass to your client under test
}
Use this pattern for services without a dedicated module, or when you need full control over files, env vars, commands, or custom wait strategies.
Postgres Module Example
Prefer the Postgres module for Postgres integration tests.
package repo_test
import (
"context"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
)
func TestRepositoryWithPostgres(t *testing.T) {
t.Parallel()
ctx := context.Background()
ctr, err := postgres.Run(ctx,
"postgres:16-alpine",
postgres.WithDatabase("app_test"),
postgres.WithUsername("postgres"),
postgres.WithPassword("postgres"),
postgres.WithInitScripts(filepath.Join("testdata", "init.sql")),
postgres.BasicWaitStrategies(),
)
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)
dsn, err := ctr.ConnectionString(ctx, "sslmode=disable")
require.NoError(t, err)
_ = dsn // open your DB client here
}
Notes:
postgres.BasicWaitStrategies()is the common default for Postgres readinessWithInitScripts(...)is useful for schema setup or seed dataConnectionString(...)is usually the easiest way to build a DB client
Redis Module Example
Prefer the Redis module for Redis integration tests.
package cache_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
tcredis "github.com/testcontainers/testcontainers-go/modules/redis"
)
func TestCacheWithRedis(t *testing.T) {
t.Parallel()
ctx := context.Background()
ctr, err := tcredis.Run(ctx,
"redis:7",
)
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)
uri, err := ctr.ConnectionString(ctx)
require.NoError(t, err)
_ = uri // pass to your redis client under test
}
Notes:
- Use module options like
WithConfigFile(...),WithTLS(), orWithLogLevel(...)when relevant ConnectionString(...)returns a ready-to-use Redis URIWithSnapshotting(...)configures Redis persistence behaviour; it is not a per-test isolation/reset mechanism
Package-Scoped Container Pattern
When most tests in a package need the same dependency, prefer a package-scoped container.
package repo_test
import (
"context"
"log"
"os"
"testing"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
)
var (
postgresDSN string
postgresCtr *postgres.PostgresContainer
)
func TestMain(m *testing.M) {
ctx := context.Background()
var err error
postgresCtr, err = postgres.Run(ctx,
"postgres:16-alpine",
postgres.WithDatabase("app_test"),
postgres.WithUsername("postgres"),
postgres.WithPassword("postgres"),
postgres.BasicWaitStrategies(),
)
if err != nil {
log.Fatal(err)
}
postgresDSN, err = postgresCtr.ConnectionString(ctx, "sslmode=disable")
if err != nil {
log.Fatal(err)
}
code := m.Run()
if err := testcontainers.TerminateContainer(postgresCtr); err != nil {
log.Printf("terminate postgres container: %v", err)
}
os.Exit(code)
}
This is a good default when:
- the container startup cost is noticeable
- most tests in the package need the dependency
- you have a clear per-test isolation strategy for data
Parallel Tests Need State Isolation, Not Just Container Isolation
Sharing one container does not make parallel tests safe by itself.
If tests run with t.Parallel(), they must not step on the same data.
Prefer one of these per-test isolation patterns.
Postgres Isolation Patterns
Preferred order:
- Per-test transaction + rollback when your code can run inside an injected transaction
- Per-test schema when your app can point each test at its own schema/search path
- Per-test database inside the same Postgres server when schema isolation is not enough
- Per-test container only when the test truly needs process-level or cluster-level isolation
Transaction pattern
Best when the application code can accept a *sql.Tx, pgx.Tx, or a narrow query interface.
- Fastest reset strategy
- Excellent for parallel tests
- Minimal container churn
Per-schema pattern
Good when each test can use a unique schema name.
- Works well with one package-level Postgres container
- Lets parallel tests run without dropping each other's tables
- Usually faster than creating a fresh container per test
Snapshot/Restore pattern
The Postgres module supports Snapshot(...) and Restore(...).
Use it when:
- migrations are expensive
- you want a quick reset to a known base state
- tests are mostly serial, or you can guarantee only one restore operation at a time
Be careful:
Restore(...)resets shared database state- do not call it concurrently from parallel tests that share the same Postgres container/database
- for truly parallel tests, prefer per-test transactions, schemas, or databases instead
Redis Isolation Patterns
Preferred order:
- Per-test logical DB when using standalone Redis and your client can select DB numbers
- Per-test key prefix/namespace when logical DB separation is not practical
- Per-test container when you need hard isolation or destructive global operations
Per-test logical DB
Good when using a standard standalone Redis image.
client := redis.NewClient(&redis.Options{
Addr: redisAddr,
DB: testDBNumber,
})
Guidance:
- Give each parallel test a distinct DB number
- Clean up with
FLUSHDBfor that logical DB only - Avoid
FLUSHALLin tests
Per-test key prefix
Good when DB-number isolation is unavailable or inconvenient.
- Prefix keys with a test-unique namespace such as
t_<id>: - Delete only that namespace in cleanup
- Safer for parallel tests than sharing raw keys
Be careful with global Redis operations:
FLUSHALLwill destroy every test's stateFLUSHDBis also unsafe if multiple parallel tests share the same logical DB
Example: Package-Level Postgres + Parallel Tests
This is usually the best tradeoff for repository/service integration tests.
- Start one Postgres container in
TestMain - Run migrations once
- Let each parallel test use its own transaction, schema, or database
Prefer this over one-container-per-test when:
- container startup dominates runtime
- the main thing you need is data isolation, not full server-process isolation
Example: Package-Level Redis + Parallel Tests
This is usually the best tradeoff for cache integration tests.
- Start one Redis container for the package
- Give each test its own logical DB or unique key prefix
- Never use global destructive cleanup across all tests
Wait Strategies and Readiness
Do not assume container start means service readiness.
Prefer:
- module-provided readiness helpers when available
wait.ForListeningPort(...)for services that only need the socket upwait.ForLog(...)when service logs are the most reliable readiness signal- combined strategies for flaky services or non-Linux host setups
Postgres specifically benefits from explicit readiness checks like postgres.BasicWaitStrategies().
Ports, Addresses, and Connection Strings
Prefer runtime discovery over fixed ports:
ctr.ConnectionString(ctx, ...)for Postgresctr.ConnectionString(ctx)for Redisctr.Endpoint(ctx, "")orctr.MappedPort(ctx, ...)for generic containers
Do not hardcode localhost:5432 or localhost:6379.
Parallel tests depend on Docker assigning distinct mapped host ports.
Cleanup Guidance
In normal tests:
ctr, err := postgres.Run(ctx, "postgres:16-alpine", postgres.BasicWaitStrategies())
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)
In TestMain:
- use
testcontainers.TerminateContainer(...)explicitly afterm.Run()
Register cleanup immediately after startup.
Reuse Guidance
WithReuseByName(...) exists, but it is experimental.
Avoid making reuse your default because it:
- weakens test hermeticity
- risks hidden state between runs
- can behave differently in local development vs CI
Prefer clean startup/teardown unless you have a deliberate local-only optimisation strategy.
Review Checklist
When reviewing testcontainers-go usage, check for:
- Module helpers used where available (
postgres.Run,redis.Run) - Modern
Run(...)APIs instead of deprecated patterns - Cleanup registered immediately
- No fixed host ports
- Explicit readiness/wait strategy where needed
- Package-scoped lifecycle chosen deliberately
- Clear per-test isolation strategy for parallel tests
- No global destructive cleanup that breaks parallel runs
- Real Postgres/Redis containers used for integration tests instead of mocks
- Postgres snapshot/restore used only when its shared-state tradeoff is acceptable
Anti-Patterns
Avoid these unless there is a strong reason:
- One heavy Postgres container per test when a package-scoped container plus data isolation would do
- Sharing one Postgres database across parallel tests with no transaction/schema/database isolation
- Sharing one Redis logical DB across parallel tests and calling
FLUSHDB - Calling
FLUSHALLin a parallel suite - Hardcoding
localhost:5432orlocalhost:6379 - Relying on container startup without readiness checks
- Treating
WithSnapshotting(...)on Redis as a test reset mechanism - Defaulting to
WithReuseByName(...)in CI - Using mocks to test SQL or Redis command behaviour that should be verified against the real service
Quick Templates
Postgres package template
var postgresDSN string
func TestMain(m *testing.M) {
ctx := context.Background()
ctr, err := postgres.Run(ctx,
"postgres:16-alpine",
postgres.WithDatabase("app_test"),
postgres.WithUsername("postgres"),
postgres.WithPassword("postgres"),
postgres.BasicWaitStrategies(),
)
if err != nil {
log.Fatal(err)
}
postgresDSN, err = ctr.ConnectionString(ctx, "sslmode=disable")
if err != nil {
log.Fatal(err)
}
code := m.Run()
_ = testcontainers.TerminateContainer(ctr)
os.Exit(code)
}
Then make each parallel test isolate its own transaction, schema, or database.
Redis package template
var redisURI string
func TestMain(m *testing.M) {
ctx := context.Background()
ctr, err := tcredis.Run(ctx, "redis:7")
if err != nil {
log.Fatal(err)
}
redisURI, err = ctr.ConnectionString(ctx)
if err != nil {
log.Fatal(err)
}
code := m.Run()
_ = testcontainers.TerminateContainer(ctr)
os.Exit(code)
}
Then give each parallel test its own logical DB or key prefix.
Source: brpaz/agent-skills — distributed by TomeVault.
先判断是否适合
作者设计意图
作者的方法与取舍
边界和复核