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

test-performance

Use when optimizing test suite performance — database setup, seeder optimization, parallel testing, CI pipeline efficiency, or RefreshDatabase alternatives.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md6.2 KB
  • evals/triggers.json2.6 KB

SKILL.md(原文)

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

test-performance

When to use

Use this skill when:

  • Tests are running too slowly (locally or in CI)
  • Database setup/teardown is a bottleneck
  • Parallel testing needs optimization
  • Seeders need performance analysis
  • CI pipeline test jobs need to be faster
  • Investigating flaky tests caused by database state

Procedure: Analyze test performance

1. Measure baseline

Before optimizing, always measure:

# Count tests per suite
find tests/ app/Modules/*/Tests/ -name "*.php" | xargs grep -l "it(" | wc -l

# Count by suite type
grep -rh "it(" tests/Unit/ app/Modules/*/Tests/Unit/ --include="*.php" | wc -l
grep -rh "it(" tests/Component/ app/Modules/*/Tests/Component/ --include="*.php" | wc -l
grep -rh "it(" tests/Integration/ app/Modules/*/Tests/Integration/ --include="*.php" | wc -l

# Count migrations
ls database/migrations/*.php | wc -l

# Count seeders
find database/seeders database/seeder-data -name "*.php" -path "*/data/*" | wc -l

2. Identify bottlenecks

The typical test lifecycle is:

Process Start → Migrate → Seed → [Test → Rollback] × N → Process End
                 ↑ expensive (once per worker)

Check these areas in order of typical impact:

AreaWhat to checkTypical impact
Migration countHow many CREATE TABLE statements?High if >20
Schema dumpIs database/schema/ used?High if missing
Seeder INSERT methodIndividual save() vs bulk insert?Medium
TruncationPer-seeder truncate vs centralized?Low (but causes correctness issues)
Connection discoveryDynamic getPdo() probing?Low
Parallel worker setupDoes each worker re-migrate?High

3. Optimization strategies (ordered by ROI)

A. Schema Dump (highest ROI)

Laravel's schema:dump consolidates all migrations into one SQL file. Instead of running N individual CREATE TABLE migrations, it loads one SQL dump.

php artisan schema:dump --database=api_database
# Generates database/schema/api_database-schema.sql

Savings: 58 migrations → 1 SQL load = ~10-25s per worker.

B. Template DB Cloning (high ROI for parallel tests)

Instead of each parallel worker running migrate+seed independently:

  1. Prepare ONE template database (migrate + seed)
  2. Clone template for each worker via mysqldump
# Prepare template
php artisan migrate:fresh --database=template_db
php artisan db:seed --database=template_db

# Clone per worker
mysqldump template_db | mysql worker_db_test_1

Savings: Eliminate per-worker migrate+seed entirely.

C. Skip Migrate+Seed Flag (high ROI for local dev)

Add a config flag to skip database setup when DB is already prepared:

// config/testing.php
'skip_migrate_seed' => EnvHelper::boolean('TESTING_SKIP_MIGRATE_SEED', false),

Developer workflow: make migrate-testing once, then make test-quick repeatedly.

D. Bulk Inserts in Seeders (medium ROI)

Replace individual $model->save() with bulk insert:

// Before: N INSERT statements
foreach ($data as $row) {
    $model = new MyModel($row);
    $model->save();
}

// After: 1 INSERT statement
MyModel::insert($data);
$models = MyModel::whereIn('id', $ids)->get();

E. Centralize Truncation (correctness fix)

Per-seeder truncation is redundant after migrate:fresh and causes:

  • Non-deterministic ordering (lazy init triggers truncate)
  • Ghost data bugs (locally passes, CI fails)

Make truncation configurable, default off:

// config/testing.php
'seed_truncate' => EnvHelper::boolean('DB_SEED_TRUNCATE', false),

F. Static Connection Discovery (cleanup)

Replace dynamic getPdo() probing with explicit config:

// config/testing.php
'connections_to_transact' => ['api_database', 'customer_database'],

4. CI-specific optimizations

  • MariaDB tmpfs: Mount data dir on RAM disk for zero I/O latency
  • Shared DB prep: One CI job prepares DB, test jobs clone from it
  • Cache test DBs: Skip re-migration if migration files haven't changed
  • Separate suites: Run no-DB tests (Unit) on cheaper runners

Related project docs

  • agents/reference/docs/seeders.md — seeder conventions (if exists)

Output format

  1. Optimized test configuration or seeder with timing comparison
  2. Parallelization or caching improvements applied

Gotcha

  • Don't use RefreshDatabase when DatabaseTransactions suffices — full refresh is 10x slower.
  • The model forgets that parallel tests share the database — use unique identifiers in test data.
  • Seeder optimization has the highest ROI — a 2s seeder running 100 times = 200s wasted.
  • Don't add indexes to test databases just for test performance — the real fix is better test design.

Do NOT

  • Do NOT use RefreshDatabase when DatabaseTransactions works — 10x slower.
  • Do NOT run full test suite on every code change — use --filter.
  • Do NOT add test-only indexes — fix test design instead.
  • Do NOT disable parallel testing to "fix" flaky tests — fix the root cause.

Where the time goes, per ecosystem

The diagnosis above is PHPUnit-shaped. The method — measure before optimising, find the slowest tests first, separate setup cost from assertion cost — transfers; the instrument does not. Resolve the runner with resolve_toolchain and read its ecosystems:

ecosystemsSlowest-test instrumentThe usual first cause
php--profile / Pest's duration columndatabase refresh per test
jsvitest --reporter=verbose, jest --detectOpenHandlesmodule transform and a leaked handle
pythonpytest --durations=20session-scoped fixtures rebuilt per test
gogo test -v, -cpuprofile, -race for the slow-and-flaky paira TestMain that starts real I/O

go test caches a package's result until its inputs change, so a suite that looks fast on the second run may not have run at all — -count=1 defeats the cache when you are measuring.

レビュー

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

同じリポジトリのスキル

概要と使いどころ

Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.

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

event4u-app/agent-config112026年10月11日 更新

Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.

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

event4u-app/agent-config112026年10月11日 更新

Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.

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

event4u-app/agent-config112026年10月11日 更新

Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.

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

event4u-app/agent-config112026年10月11日 更新

Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.

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

event4u-app/agent-config112026年10月11日 更新

Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.

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

event4u-app/agent-config112026年10月11日 更新

event4u-app のスキルをすべて見る

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