add-integration-test
Use when adding an end-to-end test scenario to remindb — symptoms include "test the full pipeline", "simulate an agent session", "verify compile→search→fetch flow", "test MCP tools end-to-end", or any task that creates a new `Test*` in `integration_test.go` / `mcp_integration_test.go` at the repo root. Distinct from per-package unit tests in `pkg/*/`.
pinned to #977b31cupdated 2 weeks ago
Ask your AI client: “install skills/add-integration-test”.
Requires the metahub MCP server installed in your client. Set up MCP.
mh install skills/add-integration-testmetahub onboarded this repo on the author's behalf.
If you own github.com/radimsem/remindb on GitHub, claim the listing to take over publishing. Your claim preserves the existing eval history and badges; only the curator label is replaced with verified-publisher on your next publish.
Stars
121
Last commit
2 weeks ago
Latest release
published
- #agent-memory
- #ai-agents
- #ast
- #claude-code
- #cli
- #codex
- #developer-tools
- #fts5
- #gemini-cli
- #golang
- #knowledge-base
- #llm-tool
- #mcp
- #mcp-server
- #model-context-protocol
- #openclaw
- #opencode
- #sqlite
- #token-efficiency
About this skill
Pulled from SKILL.md at publish time.
Integration tests live at the repo root in `package remindb_test`, not inside a `pkg/`. They exercise the full pipeline — a real store, real compiler, real MCP transport — against fixtures under `testdata/`. There are two flavors:
Evaluation report
WarningsAutomated checks the publisher passed at publish time — structure, docs, safety, and whether the artifact behaves as claimed.977b31c· 2 weeks ago
Kind-specific
31Skill: SKILL.md present
found at .claude/skills/add-integration-test/SKILL.md · frontmatter source: SKILL.md
Skill: body content present
857 words · 6,965 chars · 9 sections · 3 code blocks
Skill: triggers declaredwarn
No `trigger` phrases in SKILL.md frontmatter
Add `trigger:` lines so Claude knows when to activate this skill — e.g. `when building MCP servers` or `for diagram creation`.
Skill: allowed-tools scope
no allowed-tools restriction (Claude may use anything)
Release history
1- releasecurrent977b31cwarn2 weeks ago
Contents
Add an integration test
Integration tests live at the repo root in package remindb_test, not inside a pkg/. They exercise the full pipeline — a real store, real compiler, real MCP transport — against fixtures under testdata/. There are two flavors:
| Flavor | File | Use when |
|---|---|---|
| Direct API | integration_test.go | Testing compiler / query / store / transformer end-to-end without MCP |
| MCP | mcp_integration_test.go | Testing the user-visible tool surface as an agent would call it |
Pick the flavor by the question you're asking. "Does the compiler emit the right shape from this fixture?" → direct. "Does an agent calling MemorySearch after MemoryCompile see the expected ranking?" → MCP.
Where it lands
| File | What changes |
|---|---|
integration_test.go or mcp_integration_test.go | Add a Test<Scenario> function |
testdata/<scenario-name>/ | New fixture directory (only if existing fixtures don't match) |
Fixture directories are flat namespaces (testdata/openclaw/, testdata/<your-scenario>/). One fixture set per scenario family; reuse aggressively.
The two helpers
Both files lean on package helpers — never reach for raw store.Open or raw mcp.NewServer in a test.
internal/testutil.OpenTestDB(t)— opens an in-memory:memory:SQLite store with migrations applied; auto-cleans ont.Cleanup. Use for direct-API tests.internal/mcptest.NewEnv(t)— opens the test DB, wires a default-config server + tracker, connects an in-memory MCP transport, and exposesenv.CallTool(t, name, args)andenv.TextContent(t, result). Use for MCP tests.
Direct-API template
Mirror integration_test.go:TestOpenClawAgentWorkflow. Walk a real workflow stage by stage, log progress, assert at each stage:
package remindb_test
import (
"context"
"strings"
"testing"
"github.com/radimsem/remindb/internal/testutil"
"github.com/radimsem/remindb/pkg/compiler"
"github.com/radimsem/remindb/pkg/query"
)
func TestNewScenario(t *testing.T) {
st := testutil.OpenTestDB(t)
ctx := context.Background()
// Stage 1: compile fixtures.
result, err := compiler.CompileDir(ctx, st, "testdata/<scenario>", "<source-id>")
if err != nil {
t.Fatalf("CompileDir: %v", err)
}
if result.Added == 0 {
t.Fatal("expected nodes from fixtures")
}
t.Logf("compiled: +%d ~%d -%d (%d total)", result.Added, result.Modified, result.Removed, result.Total)
// Stage 2: query.
engine := query.NewEngine(st)
res, err := engine.Search(ctx, "<query>", 1000)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(res.Nodes) == 0 {
t.Fatal("expected search hits")
}
}
MCP template
Mirror mcp_integration_test.go:TestMcp_OpenClawAgent. The numbered-step structure is convention — each step represents one tool call an agent would make:
func TestMcp_NewScenario(t *testing.T) {
env := mcptest.NewEnv(t)
dir, _ := filepath.Abs("testdata/<scenario>")
// 1. Compile.
compileResult := env.CallTool(t, "MemoryCompile", map[string]any{
"path": dir,
"message": "<scenario>-init",
})
text := env.TextContent(t, compileResult)
if !strings.Contains(text, "compiled") {
t.Fatalf("unexpected compile result: %s", text)
}
// 2. Search.
searchResult := env.CallTool(t, "MemorySearch", map[string]any{
"query": "<keyword list>",
"budget": 1000,
})
searchText := env.TextContent(t, searchResult)
if searchText == "no results" {
t.Fatal("expected results")
}
// 3. Further stages...
}
env.CallTool already calls t.Fatalf on transport / tool errors and logs both request and response preview to t.Log. You only assert the behavioral expectations.
Cleanup is automatic
testutil.OpenTestDB(t) and mcptest.NewEnv(t) both register t.Cleanup handlers — DB is dropped, MCP session is closed, in-memory transports are torn down. Don't write your own cleanup unless you allocate something outside these helpers (e.g., a t.TempDir() you wrote files into — that's also auto-cleaned by the testing framework, no manual work needed).
Fixtures under testdata/
testdata/ is the Go-recognized name; go test excludes it from build/lint. Place a fixture directory under it per scenario, with the same file extensions the parser recognizes (.md, .yaml, .json, .jsonl, .toon).
Name fixtures by concept (testdata/openclaw/, testdata/multi-format/), not by test (testdata/test_compile_1/). Multiple tests can share a fixture; one-test-per-fixture is anti-pattern.
Quick reference
Direct API:
1. integration_test.go (Test<Scenario> with testutil.OpenTestDB)
2. testdata/<scenario>/ (fixtures matching parser-supported extensions)
3. go test ./... -run Test<Scenario>
MCP:
1. mcp_integration_test.go (TestMcp_<Scenario> with mcptest.NewEnv)
2. testdata/<scenario>/ (same fixture rules)
3. go test ./... -run TestMcp_<Scenario>
Common mistakes
- Reaching for
store.Opendirectly. Usetestutil.OpenTestDB(t)— it applies migrations, registers cleanup, and matches the assertion style of every other test. Directstore.Openskips migrations and gives you an empty schema. - Setting up the MCP transport by hand.
pkg/mcp/server_test.godoes this for unit-testing the server itself; integration tests should usemcptest.NewEnv(t). The handcrafted form has 6 lines of ceremony (NewInMemoryTransports,srv.Connect,mcp.NewClient,client.Connect,t.Cleanupfor both,SetLoggingLevelif needed) —NewEnvcollapses all of it. - Asserting on log output.
env.CallToollogs request/response previews viat.Logfor debugging. They're not part of the test contract; assert onenv.TextContent(t, result)instead. - One fixture per test. Reuse
testdata/openclaw/for any scenario where its files are appropriate. New fixture directories are for genuinely new content shapes, not new test names. - Hardcoding the absolute path to
testdata/. Usefilepath.Abs("testdata/<scenario>")likemcp_integration_test.go:14—MemoryCompilerequires absolute paths. - Forgetting
package remindb_test. Integration tests are external (use_testsuffix on the package). They exercise the public API of multiple packages — they're not allowed to import unexported names.
Cross-references
.claude/rules/go-concise.md— early returns, error handling style, named function over closure-as-var.claude/skills/add-mcp-tool/SKILL.md— when adding a tool, also extendmcp_integration_test.gowith a scenario that exercises it throughenv.CallTool.claude/skills/add-store-query/SKILL.md— when adding a query, the unit test goes inpkg/store/store_test.go; an integration test only makes sense if it changes a multi-package workflow
Reviews
No reviews yet. Be the first.
Related
orchestration-patterns
>
migration-patterns
>
deployment-sop
>
mh install skills/add-integration-test