テスト層

層コマンド備考
API unitcd apps/api && rye run pytest tests/(または make test/api)既定
analysis-core unitcd packages/analysis-core && rye run pytest tests/tests/test_pipeline_paths_integration.py でパイプライン統合
analysis-core E2E (実 LLM)OPENAI_API_KEY=… rye run pytest tests/e2e/ -v約 $0.01/run(gpt-4o-mini)。pyproject.toml の norecursedirs で既定除外、CI 非実行
API → subprocess → analysis-core 手元 smokecd apps/api && ADMIN_API_KEY=dummy PUBLIC_API_KEY=dummy OPENAI_API_KEY=dummy rye run pytest tests/manual/report_launcher_subprocess_smoke.py -q -stests/manual/report_launcher_subprocess_smoke.py。execute_aggregation() の再集約 smoke に加えて、launch_report_generation() から 通常フロー全体 を本物の subprocess で起動し、hierarchical_result.json / hierarchical_status.json / report_status.json 更新まで確認する。full flow 側は local provider と OpenAI 互換の偽 LLM で extraction / embedding / clustering / overview まで踏む。既定収集の対象外で、明示実行専用。source-codeより
Frontend unit (Jest)apps/public-viewer/ と apps/admin/ で pnpm test
Browser E2E (Playwright)cd test/e2e && pnpm test(UI: pnpm run test:ui)設定詳細は test/e2e/CLAUDE.md

Lint / format

  • Python: ruff — rye run ruff check .、または make lint/api-check / make lint/api-format
  • TS/JS: Biome(ESLint + Prettier の代替)— 各 app で pnpm run lint / pnpm run format
  • lefthook が pre-push で ruff check + ruff format --check を実行。Biome は skip: true で gating されていない
  • CI にも Biome の workflow は無く、main の全体 lint は 2026-02 以降落ちたまま。PR では「変更ファイルだけ Biome 成功」を確認する慣行。経緯は biome-lint-main-drift-2026-10-09
  • PR #963(未merge)で 3 ディレクトリを 0 件にし、client build / client-admin build に biome ci を追加。マージ後は全体 lint が PR の gate になる。lint gate は 0 件化と同じ PR で入れないと戻る(biome-lint-main-drift-2026-10-09 の教訓)

CI ワークフロー

.github/workflows/ 配下(docs/testing.md で列挙):

  • server-pytest.yml
  • client-jest.yml
  • client-admin-jest.yml
  • e2e-tests.yml
  • ruff-check.yml

docs/testing.md には Biome 系 CI への明示的言及がない — フロントエンドの lint enforcement はバックエンドより弱い可能性。

Playwright + Next.js のコツ

skills/kouchou-ai-testing/SKILL.md より:

  • page.goto 後は必ず await page.waitForLoadState("networkidle")
  • Server Components は実 HTTP を投げるので dummy server を立てる
  • ハンドメイドの dummy より、本番形のフィクスチャを使うべし

既知の歴史的事故

  • meeting-minutes 2025-10: import-order を ruff の lint がエラーにし続け、無関係 PR が全部ブロックされた → PR #708 で import-order チェックを無効化してすべての既存違反を一括修正
  • meeting-minutes 2025-09 / PR #553: テストデータ汚染インシデント
  • Devin がリント自動修正できないものを無限ループした事例も同時期(→ coding-agents)

現在の運用判断

  • analysis-core の hierarchical_clustering が出す UMAP の UserWarning(random_state 固定により並列性が制限される旨)は、2026-05-17 時点では 既知で許容。再現性優先の副作用とみなし、将来 seed / 並列性オプションを追加する時に再検討する。gotchas / source-codeより

v5 移行期のテスト責務

2026-05-18 時点の計画では、9 月までに v4 の既存機能が壊れていないことをテストで保証しつつ、発展性の高い v5 へ移行する ことが重視されている。book-release-development-plan-2026-09より

したがって移行期のテストは、単に main が green かを見るだけでなく:

  • v4 で守るべきユースケースを固定する
  • v5 default path でもそのユースケースが壊れていないか確認する
  • unit だけでなく integration / E2E を回帰検知帯として扱う

という責務を持つ。

Open Questions

  • E2E は CI 非実行のため、回帰検知はローカル運用次第。ステージング環境ベースの代替戦略の合意は未確認
  • Biome の CI ゲーティングは「無い」と確定(2026-10-09、biome-lint-main-drift-2026-10-09)。入れるなら一括修正で 0 にしてから biome ci を build workflow に足す順序

Updates

  • 2026-10-09: Biome が hook / CI のどこでも強制されておらず main の全体 lint が落ちている事実と、その由来を biome-lint-main-drift-2026-10-09 に記録
  • 2026-05-17: UMAP の random_state 由来 warning は既知で、現時点では許容する判断を追記
  • 2026-05-17: 初回作成
  • 2026-05-18: v5 移行期における「v4 回帰保証」のテスト責務を追記
  • 2026-05-23: API の report_launcher が analysis_core を subprocess で起動する継ぎ目を、mock ではなく実 subprocess で踏む手元 smoke test (tests/manual/report_launcher_subprocess_smoke.py) を追加
  • 2026-05-23: launch_report_generation() から通常フロー全体を踏む manual smoke を追加し、その実行で workflow plugin が --input-dir / --output-dir を legacy step に渡していなかったバグを発見・修正

Updates — 2026-10-05 検証結果の保証範囲を分ける

9月9日の#943・#945・#946の記録をもとに、テスト結果の読み方を整理した。今回のコード再検証ではない。three-issues-progress-2026-09-09 / next-three-issues-progress-2026-09-09より。

  • Server ActionからAPIへの通信はブラウザのpage.routeでは捕捉できないため、HTTP dummyで失敗応答・切断を作る。画面側の復帰動作の確認と、実プロバイダーの認証・接続確認は区別する。
  • fixtureによるブラウザ試験は操作と値の受け渡し、実routerと一時ファイルの統合試験は保存・再取得を担う。設定画面では他項目の保持、不正値の拒否、取得失敗時に既定値で上書きしないことも確認する。
  • Jest成功だけでは型検査成功を保証しない。#946ではChakra Textのlabel属性がビルド時に失敗し、asChildとnative labelで修正した。CI成功・自動レビュー完了・実サービス接続成功・ブラウザエラー不存在も、それぞれ別の確認結果として報告する。

上のOpen Questionsにある「E2EはCI非実行」は、ブラウザE2E全般の現在の説明としては使わない。9月9日の#943では全体86件、#946では81件のブラウザE2EがCIで成功している。実LLMを使うanalysis-core E2Eとは対象を区別する。