本文へ移動
cccskills
無料GitHub で公開

docker-compose-tests

Authors a `compose.test.yaml` for tests - declares the SUT plus its real backing services as one declarative topology, wires healthcheck-driven `depends_on: condition: service_healthy` start ordering, isolates parallel CI jobs via per-job `--project-name`, gates the test step on `--wait` / `--wait-timeout` / `--exit-code-from`, and tears the stack down deterministically with `down --volumes --remove-orphans`. Use when the test environment is multi-service (app + db + cache + queue) and the topology is best expressed in YAML rather than imperative test code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qaスター 13(GitHub 13 + cccskills 0)
連携ツールPostgreSQLPlaywright

実行スコア 未検証

インストール方法を見る

含まれるファイル(4)

  • SKILL.md10.5 KB
  • .tessl-plugin/plugin.json699 B
  • references/anti-patterns.md2.5 KB
  • references/compose-flags.md2.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

docker-compose-tests

Reach for Compose in tests when the SUT has two or more real backing services that must see each other (app -> db -> cache -> queue), the same topology must run locally and in CI without imperative drift, or parallel CI jobs each need an isolated stack. For a single dependency wired into one test, testcontainers is lighter - it lives inside the test process with no separate docker compose up step.

Step 1 - Author compose.test.yaml

Compose's default file lookup is compose.yaml or docker-compose.yaml in the working directory or any parent (compose-cli); using the explicit compose.test.yaml filename + -f flag keeps test topology separate from local-dev topology.

# compose.test.yaml
name: orders-tests

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: ${PG_PASSWORD:?set PG_PASSWORD}
      POSTGRES_DB: orders_test
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d orders_test"]
      interval: 2s
      timeout: 3s
      retries: 30
      start_period: 5s

  cache:
    image: redis:7
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 2s
      timeout: 3s
      retries: 30

  app:
    build:
      context: .
      target: test
    environment:
      DATABASE_URL: postgres://postgres:${PG_PASSWORD}@db:5432/orders_test
      REDIS_URL: redis://cache:6379/0
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 2s
      timeout: 3s
      retries: 30
      start_period: 10s

  e2e:
    image: mcr.microsoft.com/playwright:v1.50.0-noble
    working_dir: /work
    volumes:
      - .:/work
    environment:
      BASE_URL: http://app:3000
    depends_on:
      app:
        condition: service_healthy
    command: npx playwright test

The name: top-level key sets the project name (which Compose normally derives from the working directory) - important for CI isolation, see Step 4.

Even a throwaway test database gets its password from the environment (a CI secret, or a git-ignored .env locally), never a literal in the compose file. Per Compose interpolation, ${VAR} is read from the shell or .env, and ${VAR:?error} stops Compose when it is unset.

Step 2 - Healthchecks are load-bearing

service_started (the depends_on default) is almost never what a test wants. Postgres "started" doesn't mean "accepting connections". Always pair a real dependency with a healthcheck and gate its dependents with condition: service_healthy. The three depends_on conditions are tabulated in references/compose-flags.md.

The healthcheck syntax per compose-services:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3
  start_period: 40s

For tests, use shorter intervals (2s vs the 1m30s default) and more retries so the gate trips quickly when the service is up but waits long enough for cold starts.

Step 3 - Migrations as one-shot dependencies

Database migrations belong in their own service that the app depends_on with service_completed_successfully:

services:
  db:
    image: postgres:15
    healthcheck: { test: ["CMD-SHELL", "pg_isready"], interval: 2s, retries: 30 }

  migrate:
    image: orders-app:test
    command: npm run db:migrate
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://postgres:${PG_PASSWORD}@db:5432/orders_test

  app:
    image: orders-app:test
    depends_on:
      db: { condition: service_healthy }
      migrate: { condition: service_completed_successfully }
    environment:
      DATABASE_URL: postgres://postgres:${PG_PASSWORD}@db:5432/orders_test

The chain - db healthy → migrate runs → migrate exits 0 → app starts - ensures the app never connects to an unmigrated database.

Step 4 - Per-job isolation in CI

Per compose-cli, the project name controls the namespace of every resource Compose creates (containers, networks, volumes). Two parallel jobs that use the same project name fight each other.

Set the project name from a unique-per-job value:

# .github/workflows/integration.yml
jobs:
  e2e:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3, 4]
    env:
      COMPOSE_PROJECT_NAME: orders-${{ github.run_id }}-${{ matrix.shard }}
    steps:
      - uses: actions/checkout@v5
      - name: Compose up
        run: docker compose -f compose.test.yaml up --build --wait --wait-timeout 180
      - name: Run tests
        run: docker compose -f compose.test.yaml run --rm e2e
      - name: Compose down
        if: always()
        run: docker compose -f compose.test.yaml down --volumes --remove-orphans

The -p / --project-name resolution order is: flag > COMPOSE_PROJECT_NAME env var > top-level name: > directory basename. Using the env var keeps the YAML clean while overriding the in-file name: per CI job.

"Project names must contain only lowercase letters, decimal digits, dashes, and underscores, and must begin with a lowercase letter or decimal digit." (compose-cli)

Step 5 - Gate the test step on readiness

Two up flags pair for "block until everything is healthy": --wait ("Wait for services to be running|healthy. Implies detached mode.") and --wait-timeout <seconds> ("Maximum duration in seconds to wait for the project to be running|healthy") (compose-up). The full flag table (--abort-on-container-exit, --abort-on-container-failure, --exit-code-from) is in references/compose-flags.md.

Two valid CI shapes:

Shape A - up --wait then run the test service

docker compose -f compose.test.yaml up --build --wait --wait-timeout 180
docker compose -f compose.test.yaml run --rm e2e
EXIT=$?
docker compose -f compose.test.yaml down --volumes --remove-orphans
exit $EXIT

The up --wait step blocks until every service is healthy or the 180s budget elapses. The run step executes the test container; its exit code is the build verdict.

Shape B - up --abort-on-container-exit --exit-code-from <test-service>

docker compose -f compose.test.yaml up \
  --build \
  --abort-on-container-exit \
  --exit-code-from e2e

Compose returns the test container's exit code as its own. Cleaner when the test runs as a Compose service rather than via run.

Step 6 - Tear down deterministically

down stops and removes containers and networks (compose-cli). Two flags matter for tests: --volumes / -v (remove named volumes, else DB state persists across runs and the next run sees stale data) and --remove-orphans (remove containers for services no longer in the file). The full table is in references/compose-flags.md.

docker compose -f compose.test.yaml down --volumes --remove-orphans

Always run down in an if: always() step (GitHub Actions) or trap-on-EXIT (shell) - leaked containers consume CI runner disk and poison the next run.

Step 7 - Profiles for selective enablement

When the test compose file has services that aren't always needed (seeded fixtures, a debugging admin UI, a heavyweight observability stack), gate them behind a profile:

services:
  db: { image: postgres:15, healthcheck: { ... } }

  pgadmin:
    image: dpage/pgadmin4
    profiles: [debug]
    ports: ["5050:80"]
    depends_on: { db: { condition: service_healthy } }

Run with the profile when needed:

docker compose -f compose.test.yaml --profile debug up
# or via env:
COMPOSE_PROFILES=debug docker compose -f compose.test.yaml up

Per compose-cli: "Specify a profile to enable" - multiple profiles via repeating --profile or comma-separated COMPOSE_PROFILES.

Anti-patterns

Common failure modes and their fixes - missing service_healthy gates, shared project names across parallel jobs, down without --volumes, foreground up without --abort-on-container-exit, migrations in the app entrypoint, host bind mounts in CI, reusing the dev compose file, and hard-coded host ports - are cataloged in references/anti-patterns.md.

Limitations

  • Compose is not a scheduler. It runs on one Docker daemon. For multi-host or k8s-shaped tests, use the orchestrator's native test primitive (kind, k3d, helm test) instead.
  • No native parallelism within one project. Compose runs services in topological order; "parallel" tests come from running multiple Compose projects per CI matrix shard.
  • Healthcheck images need the probe binary. Minimal/distroless images often don't ship curl / pg_isready - either switch to a slim variant or use a TCP probe via nc / wget.
  • Per-test reset is coarse. The Compose stack is per-suite; for per-test DB reset, layer a snapshot/restore step on top.

References

  • compose-overview - overview, "tool for defining and running multi-container applications".
  • compose-cli - docker compose subcommand list, -f, --project-name, --profile, project-name resolution rules.
  • compose-up - up flags: --wait, --wait-timeout, --abort-on-container-exit, --exit-code-from, --build.
  • compose-svc - services schema: healthcheck, depends_on conditions (service_started / service_healthy / service_completed_successfully).
  • testcontainers - alternative when the topology is one container per test, expressed in test code.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

Builds a CI gate that fails the build on **new** WCAG / a11y violations introduced by a PR while grandfathering pre-existing violations on a per-rule / per-page baseline. Aggregates verdicts from axe-core / pa11y / Lighthouse a11y / WAVE / IBM Equal Access scans. Use when a project has accumulated a11y debt and a strict "zero violations" gate would block every PR - the ratchet pattern lets the team ship while preventing regressions.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Workflow skill that builds an A/B-test validity checklist from an experiment proposal, walking the canonical design-correctness gates - pre-registered OEC/power/guardrails, randomization unit + SRM check, assignment integrity, telemetry, peeking discipline, novelty/primacy, post-experiment SRM re-check - into a per-experiment checklist + sign-off form. Use when launching, auditing, or governing an experiment. For pitfall mechanics (guardrails, peeking) see experiment-results-interpreter's references; to read an already-valid result use experiment-results-interpreter; for per-SDK harness tests use experiment-sdk-testing - this gates DESIGN, not SDK code.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

The single install-flow skill: the reference contract for the PWA install flow (installability gate fields, `beforeinstallprompt` handshake, per-platform paths - Android WebAPK / iOS Share menu / Firefox no-op - and the `display-mode` post-install signal, in references/install-flow-reference.md) plus the build-an-X workflow that emits the Add-to-Home-Screen suite. Walks the four-stage timeline, emitting one test per gate cell per [web.dev/articles/install-criteria][install-criteria], the deferred-prompt → `prompt()` → `userChoice` chain per [web.dev/articles/customize-install][customize-install], the iOS Safari manual-metadata branch (`apple-touch-icon`) per [web.dev/learn/pwa/installation][learn-pwa], and the post-install `(display-mode: standalone)` MQ assertion. Output: a Playwright spec with per-stage cells plus a coverage matrix. Use when a PWA's manifest, icons, or install handler change, when install conversion drops at an unknown stage, or when triaging a flaky install assertion.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Build-an-X workflow that uses an LLM to map existing tests to spec sections - given a spec doc + the test suite, the LLM identifies which tests cover which sections, surfaces uncovered sections (gap), and recommends specific tests to add. Output is a coverage matrix per spec ID. Scope is mapping tests that already exist and naming the gaps, not authoring tests for new acceptance criteria. Use when a spec doc and a test suite both exist but nobody can say which requirements are actually covered - before a release sign-off, an audit, or a decision about where to spend the next round of test effort.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Generates tests from natural-language specs (acceptance criteria, user stories, requirements) using an LLM, with confidence scoring per test case (LLM self-assessment plus heuristics: assertion quality, naming, completeness), batching uncertain cases for human review, and integration with the team's existing test framework. Use when the user asks to generate unit tests from acceptance criteria, convert user stories to test cases, automate test creation from requirements, or augment a spec-driven test suite with AI-generated stubs that are then curated before merge.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

Configures Allure Report (test-runner adapter install, `allure-results` directory wiring, `categories.json` for failure classification, `history-trend.json` retention via the copy-history-between-runs pattern), runs the Allure CLI to convert `allure-results` to a static HTML site, and uploads the report as a CI artifact. Use when the team needs richer test reporting than JUnit XML - step-level attachments, per-test history, retry tracking, and severity / epic / feature labeling across framework-agnostic adapters (pytest, Jest, JUnit, TestNG, NUnit, Mocha). As a rich static HTML report generator, it is the open-source alternative to the sunset ExtentReports (JVM/.NET per-test HTML narrative); for hosted cross-run flakiness analytics rather than a static per-run report use currents-integration.

日本語の概要は準備中です。原文の説明を表示しています。

testland/qa132026年10月20日 更新

testland のスキルをすべて見る

このスキルの問題を報告する