Write integration tests with real dependencies
Writes integration tests that run against real dependencies such as databases and queues in containers, with fixtures, isolation between tests and cleanup. Use when mocks hide bugs at the boundary.
Integration tests exist to catch what mocks cannot: SQL that only fails on the real engine, transaction and locking behaviour, migrations, serialisation across a queue, unique constraints, time zones and encodings. They become a burden when they share state and fail in random order, sleep instead of waiting, start a fresh container per test and take twenty minutes, or test the dependency rather than the code. Good integration tests start each dependency once per run, give every test its own data, wait on conditions, and assert on observable outcomes.
Write integration tests for:
Only if [DEPENDENCIES] is given: Dependencies:
- Read the code and the project's existing test setup (framework, runner, folders, helpers, migrations, CI config). Follow what exists. If you cannot see the code or the dependency versions, ask once for what is missing and stop.
- Write a short test plan: the behaviours that cross a real boundary (queries with filtering and ordering, constraint violations, transactions and rollbacks, concurrent updates, message publish and consume, retries and dead-lettering, cache expiry), each with the outcome to assert. Leave pure logic to unit tests.
- Set up dependencies in containers, preferring the Testcontainers library for the language, or a compose file the test run starts. Pin image versions to match production. Start each container once per test run or suite, not per test. Apply the real schema migrations, not a hand-written schema.
- Isolate tests. Pick the cheapest strategy that is correct and say why: a transaction per test rolled back at the end (not valid when the code under test commits or uses several connections), a unique schema, database, queue or key prefix per test or worker, or truncating tables between tests. Make tests safe to run in parallel or mark them serial.
- Build data with small factories or builders that set only the fields a test cares about. No shared mutable fixtures.
- Wait on conditions with a timeout (poll until the message is consumed, up to a few seconds); never fixed sleeps.
- Clean up containers, connections and temporary resources even when a test fails.
- Run the tests and report the real result. If you cannot run them (no container runtime), say so plainly.
- Use the real dependency for the behaviour under test; mock only external third parties you do not control, and say which.
- Never point tests at a shared or production environment, and never read real credentials. Use container-generated connection settings.
- Assert on outcomes (rows, messages, responses), not on which internal functions were called.
- Fix the behaviour, not the test. Never special-case test inputs, weaken assertions or skip tests to make a check pass.
- If a test looks wrong, explain why and ask before changing it.
- Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
- If you could not run a check, say so plainly and say which one.
Test plan
A table: behaviour, dependency, assertion.
Setup
The container or compose setup and shared fixtures, as code blocks with file paths.
Tests
The test files, as code blocks with file paths.
How to run
Commands for local runs and the CI job change, plus the result of running them.
Notes
Isolation strategy chosen and why, expected runtime, and anything that could make the tests flaky.
1 required value still a placeholder; the assistant will ask for it.
details
- kind
- Prompt: a task you run by name to get one finished thing back
- domain
- Software engineering
- category
- Testing
- level
- Intermediate
- made for
- Backend engineer, Software engineer, QA / test engineer, Full-stack engineer
- needs
- repo-read, file-write, shell
- risk
- runs-commands
- version
- v1.0.0 · incubating
- reviewed
- 2026-10-03
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md
use in
npx @hermes-hq/hodios install write-integration-tests --target claude-codenpx skills add hermes-hq/hodios-dist --skill write-integration-tests -a claude-codeclaude plugin marketplace add hermes-hq/hodios-distclaude plugin install hodios-software-engineering@hodiosThe plugin brings every entry in this domain at once.
pairs well with
All of TestingTest engineer
Designs and writes tests that catch real regressions, chooses the cheapest test level that proves a behaviour, and refuses flaky or assertion-free tests. Use as a testing persona or subagent.
test-engineerWrite unit tests
Writes unit tests that pin a unit's behaviour, covering boundaries, errors and edge inputs in the project's own test style, and proves each test can fail. Use for new or untested code.
write-unit-testsWrite consumer-driven contract tests
Writes consumer-driven contract tests between two services and the CI gate that runs them, so a breaking API change fails before deploy. Use when services that call each other ship independently.
write-contract-testsFix a flaky test
Finds why a test passes and fails intermittently and fixes the cause instead of adding retries. Use when a test fails only sometimes, locally or in CI.
fix-flaky-testWrite a Docker Compose dev environment
Writes a Docker Compose local development setup that mirrors production dependencies, with health checks, named volumes, seed data, env files and a one-command start. Use when onboarding developers.
write-docker-composeReview test quality
Reviews a test suite or diff for weak assertions, over-mocking, hidden coupling, sleeps, nondeterminism and tests that cannot fail, with a concrete rewrite for each problem. Use when reviewing tests.
review-test-quality