testing
テストの記述ガイドライン。テストを書くとき、テスト設計を考えるとき、テスト戦略を議論するときに使用する。テストの目的、構成、書き方の原則に基づき、信頼性が高く保守しやすいテストを書く。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
テストの記述ガイドライン。テストを書くとき、テスト設計を考えるとき、テスト戦略を議論するときに使用する。テストの目的、構成、書き方の原則に基づき、信頼性が高く保守しやすいテストを書く。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Preview generated Markdown (plans, design notes, reviews, research reports) in the user's browser. Use when sharing long, structured output — documents with headings, tables, code blocks, or Mermaid diagrams — that is hard to read in the terminal.
OpenAI Codex CLIを使ってコードや計画に対する外部視点のレビューを取得する。計画の妥当性確認、複雑な問題で行き詰まったとき、アーキテクチャ判断のセカンドオピニオン、難しいデバッグのときに使用する。「Codexに聞いて」「セカンドオピニオンが欲しい」などのリクエストにも対応する。
freshターミナルエディタでファイルを開く操作。ユーザーが「freshで開いて」「このファイルをエディタで見たい」「編集したい」と言ったとき、cmux経由でfreshを別ペインに起動してファイルを開く。
cmuxターミナル内での操作スキル。CMUX_*環境変数が存在する場合、cmuxのCLIコマンドを使う前に必ずこのスキルを読む。ペイン分割、コマンド送信、ブラウザ自動化、通知、サブエージェントの隔離実行など、cmux操作全般で使用する。「別ペインで開いて」「横に表示して」「ブラウザで確認して」などのときにも使用する。
k8oが好むUIデザインの方針。UIコンポーネントの作成、画面デザイン、スタイリングの判断時に使用する。ArteOdysseyを使うプロジェクトではコンポーネントやトークンの具体的な使い方を、それ以外のプロジェクトではデザインの方向性を提供する。自由にデザインを作るとき、見た目の判断に迷ったとき、UIレビュー時にも使用する。
Conventional Commitsに従ったアトミックなgitコミットを作成する。変更を論理単位に分割し、独立してrevert可能なコミットを生成する。コードの変更をコミットしたいとき、コミットメッセージを作りたいときに使用する。
| name | testing |
| description | テストの記述ガイドライン。テストを書くとき、テスト設計を考えるとき、テスト戦略を議論するときに使用する。テストの目的、構成、書き方の原則に基づき、信頼性が高く保守しやすいテストを書く。 |
テストの目的は「コスト削減」ではなく、高い信頼性の実行結果に短い時間で到達し、開発者に確信を与え、ソフトウェアの継続的な成長を可能にすること。
テストでは品質は上がらない。品質を上げるのはプログラミング。テストは品質が保たれていることを確認する手段。
テストがもたらす価値は3つ:
「あとで書く」テストは、これらの価値のうち(2)と(3)を大きく損なう。振る舞いを決める前にテストを書くと、テストが仕様を駆動する。
Red → Green → Refactor を小さく速く回す:
「動作するきれいなコード」は1度に書かない。動作させる → きれいにする の2段階に分ける。
Green に進むときの選択肢:
| パターン | やり方 | 使う場面 |
|---|---|---|
| 仮実装 (Fake It) | 期待値をベタ書きで返す | 最初の一歩、不安なとき |
| 三角測量 (Triangulation) | 2つ目・3つ目のテストで一般化を強制 | 仮実装からの脱却、複雑な分岐 |
| 明白な実装 (Obvious Implementation) | いきなり本実装を書く | ロジックが自明で自信があるとき |
不安なら仮実装から。自明なら明白な実装で。途中で詰まったら一段階戻す。
全てのケースを試すのは不可能。バグが潜みやすい所に優先して書く。
不具合は境界(0、1、最大、最小、空、オーバーフロー)に集まる。n < 10 のテストなら、9, 10, 11 を試す。
入力空間を「同じ振る舞いをするはずのグループ」に分け、各グループから代表を1つ選ぶ。全網羅より、クラス分けして代表を押さえる方が効率的。
すべてのコードに同じ密度でテストを書かない。複雑な分岐・外部境界・過去に壊れた所・仕様変更の多い所にテストを集中する。トリビアルな getter/setter にテストはいらない。
テストを分類するときは、スコープ(単体/統合/E2E)よりもサイズで考える。
| サイズ | 制約 | 特性 |
|---|---|---|
| Small | 単一プロセス、メモリ内 | 高速、決定的、安定 |
| Medium | 単一マシン(DB、ファイル可) | やや遅い、不安定性のリスク |
| Large | 制約なし(外部サービス可) | 遅い、不安定、高コスト |
テストピラミッド: Smallを多く、Mediumを中程度、Largeを少なく。アイスクリームコーン(Largeが多い状態)は避ける。
テスト設計のトレードオフを評価する5軸:
全てを最大化はできない。プロジェクトの状況に応じてバランスを取る。
テストが失敗したとき、それは本物の問題であるべき。
偽陽性が多いテストスイートは、やがて無視されるようになる。
// ❌ 実装に結合(内部stateの値を確認)
expect(component.state.count).toBe(1);
// ✅ 振る舞いを確認(ユーザーが見る結果)
expect(screen.getByText('1')).toBeInTheDocument();
テストコードにプロダクトコードと同じロジックを書かない。
// ❌ 自作自演: テスト側でも同じ計算をしている
const expected = (130 / (1 + (8 / 100))) * (8 / 100);
expect(item.taxAmount()).toBe(expected);
// ✅ 期待値はリテラルで書く
expect(item.taxAmount()).toBe(9.629629629629629);
// ❌ 情報が少ない
expect(result === 40).toBe(true);
// ✅ 失敗時に期待値と実際の値がわかる
expect(result).toBe(40);
テスト間の実行順序に依存しない。各テストが単独で実行できる状態を保つ。
結果が不安定なテスト(同じコードで成功/失敗が変わる)は即座に対処する。放置するとテストスイート全体の信頼性が崩壊する。
// Arrange: 準備
const cart = createCart();
cart.addItem({ name: 'Widget', price: 100 });
// Act: 実行
const total = cart.getTotal();
// Assert: 検証
expect(total).toBe(100);
1つのテストで1つの振る舞いを検証する。複数の検証を詰め込まない。テスト名は検証する振る舞いを表現する。
テストが書きにくいコードは、設計に問題がある兆候。テスト容易性を下げている要素を特定し、切り出す(Humble Objectパターン)。
テスト容易性を下げる要素:
これらを境界に押し出し、コアロジックをテストしやすくする。
詳細は references/test-doubles.md を参照。