testing について
testingは、開発者やコーディングエージェント向けのテスト戦略スキルです。テスト層の選択やテスト容易性の改善、エージェントが書いたコードへの対策を支援します。
主な機能
- 01適切なテスト層の選択
- 02観察可能な振る舞いの検証
- 03モックより実際の協力先を優先
- 04コーディングエージェント向けテストの指針
- 05本番環境のフィードバック手法
活用シーン
- 01新機能のテスト計画
- 02書きにくいテストから設計上の問題を発見
- 03エージェント作成コードへの保護策
- 04脆弱または過大なE2Eテストの削減
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bsene/ skills --skill testingインストール後、Claude Code で/testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/acceptance-testing.mdai-agent-testing.mdasync-and-time.mdbdd-review.mdmartin-fowler-testing.mdmocks-and-fragility.mdprinciples.mdsmoke-tests.mdtcrdd.mdtdd-and-atdd.mdtest-strategy.mdtestdesiderata.mdtrustworthy-tests.mdunit-testing-principles.mdweb-api-testing.mdxp-testing-practices.mdreferences/smoke-tests/curl.mdhurl.mdreferences/tcrdd/autonomous-execution.mdbenchmarks.mdexample-and-errors.mdfurther-reading.mdgit-cycle.mdphase-guide.mdpragmatics.md詳細
テスト — 戦略と理念
テストは事後の検証ではありません。設計へのフィードバックです。書きにくいテストは、本番コードに結合があることを明らかにします。名前を付けにくいテストは、振る舞いについての考えが曖昧であることを明らかにします。テストスイートはシステムの生きた仕様です。つまり、コードが実際に何をするべきかを示すものです。人間がコードを書いた場合でも、AI エージェントが書いた場合でも、それは変わりません。
中核となる信念
| 信念 | 実践での意味 | 防止するアンチパターン |
|---|---|---|
| テストしにくいなら設計に問題がある | テストではなく設計をリファクタリングします | テスト可能にするためにあらゆるものをモックすること |
| テストは検証ではなく仕様です | 振る舞いを説明する文としてテストに名前を付けます | 実装の詳細にちなんだ名前のテスト |
| モックは戦略ではなくコードの臭いです | 実際の協力オブジェクトまたはフェイクを優先します | バグがあっても通過してしまう、モックだらけのテストスイート |
| 純粋関数はテスト容易性の理想です | I/Oを端に寄せ、ビジネスロジックを純粋に保ちます | 副作用と絡み合ったビジネスロジック |
| グリーンならリリース可能でなければなりません | ビルドの失敗はノイズではなく、作業を止める合図です | テストスイートがたまたま通るまで、不安定なテストを再試行すること |
| 設計原則ではなく振る舞いをテストします | SRPなどのアーキテクチャ上のルールはコードの構成方法を導きます。設計ルールに従っているかではなく、コードが何をするかをアサートします | メソッド数を数えたり、クラスの責務を確認したり、観測可能な結果ではなくSOLIDへの準拠をアサートしたりするテスト |
テストポートフォリオ
テストピラミッドが示すのは、有用なデフォルトの構成であって、絶対的なルールではありません。ユニットテストは高速で正確なため、土台を形成します。より高レベルのテストにも価値があります。配線、連携、ユーザージャーニーを検証できるためです。ポートフォリオの原則は、シナリオに必要な信頼性を得られる、最もコストの低いレイヤーを選ぶことです。
| レイヤー | 数 | 速度 | 目的 | 脆弱性 |
|---|---|---|---|---|
| ユニット | 多数 | ms | 純粋な動作の仕様化 | 動作に焦点を当てれば低い |
| コンポーネント | いくつか | ms~秒 | デプロイ可能な単一サービスをパブリックインターフェース経由で検証 | 低~中 |
| 統合 | いくつか | 秒 | 1つのプロセス/システム内の実際の連携先を検証 | 中 |
| コントラクト | いくつか | ms~秒 | サービス境界におけるコンシューマー/プロバイダーの期待 | コントラクトに焦点を当てれば低い |
| E2E/UI | 少数 | 秒~分 | これまでにないユーザージャーニー | 高 — 最小限に抑える |
| 本番環境 | 継続的 | ほぼリアルタイム | 合成モニタリングとドメインの可観測性 | 運用上のもの — 代替にはならない |
高レベルのテストでバグが見つかった場合は、修正する前に、役立つ最も低いレベルで再現してください。焦点を絞った回帰テストが恒久的な安全策となり、高レベルのテストは発見の仕組みとなります。
判断ガイド
| 質問 | 回答 → アクション |
|---|---|
| これは純粋な動作ですか、それとも配線に関する問題ですか? | 純粋な動作 → ユニットテスト、配線 → コンポーネント/統合テスト |
| シナリオはサービス境界を越えますか? | はい → コンシューマー/プロバイダーの期待を確認するコントラクトテストを実施し、E2Eは1つのジャーニーに限定する |
| これは重要なユーザージャーニーですか? | E2Eテストを1つ作成し、バリエーションは下位レイヤーに移します |
| モックが必要ですか、それとも実際の連携先を使えますか? | 実際の連携先を優先します。モックは、外向きのやり取り自体が動作である場合に限ります |
| テストを書くのが難しいですか? | それを設計に関するフィードバックと捉え、テストダブルを追加する前にリファクタリングします |
| テストはタイミングや非決定的なI/Oに依存していますか? | 設計を修正します。高速なテストは決定的である必要があります |
| 期待どおりに失敗する様子をこのテストで確認したことがありますか? | いいえ → 明らかなバグを仕込み、失敗を確認してから元に戻します |
| 本番環境の動作に驚かされる可能性がありますか? | 合成モニタリング、ドメインの可観測性、または探索的な調査を追加します |
| 主導するのは誰ですか — 人間ですか、それともAIエージェントですか? | 人間 → TCRDD のマイクロステップ、エージェント → 信頼性を示すシグナルを分けたテストファーストのバッチ |
AI コーディングエージェントによるテスト
厳格なレッド/グリーン/リファクタのサイクルは、_人間_の短期記憶を管理するためのものです。エージェントは正反対の特性を持っています。作業メモリは大きい一方で、幻覚を起こしたり、テストを満たすのではなく、テストの抜け道を探したりする傾向があります。開発のサイクルと信頼モデルは、どちらも適応させる必要があります。
| 従来の前提 | エージェント時代の調整 |
|---|---|
| 素早くフィードバックを得るため、細かいステップでTDDを強制する | エージェントに先にテストを書かせ、その後、より大きなバッチで実装させる |
| 作成者は自分のコードをテストできる | バグを仕様化したテストを防ぐため、テスト作成者とコーダーの役割を分ける |
| コードレビューが主な包括的な検出手段である | カバレッジ、ミューテーションテスト、複雑度メトリクス、重点を絞った人間によるレビューを組み合わせる |
| 受け入れテストは通常のコード成果物である | 受け入れテストをコーディングエージェント向けの不変のガードレールとして扱う |
| 差分は小さいほど常に良い | 差分を小さくするためにテストを散在させるより、一貫性のあるテストグループを優先する |
| 本番環境でのチェックは任意である | プロンプト/出力の品質、ドリフト、レイテンシ、障害モードを継続的に監視する |
パイプライン全体と信頼モデルについては、AI コーディングエージェントによるテストを参照してください。LLM アプリケーションについては、Martin Fowler のテスト・カノンもお読みください。
テストのアンチパターン
| アンチパターン | 問題 | 解決策 |
|---|---|---|
| モックの使いすぎ | モックによって統合時のバグが隠れる | 実際の協力オブジェクトかフェイクを優先する |
| 実装のテスト | リファクタリングでテストが壊れる | メソッド呼び出しの関係ではなく、観測可能な振る舞いをテストする |
| 壊れやすい/不安定なテスト | 結果がノイズになる | 状態を分離し、時間、乱数、非同期処理の完了を制御する |
| 遅いユニットテスト | 設計の結合度が高すぎる | テストではなく設計をリファクタリングする |
| E2E テストに偏重したスイート | 効果が逓減し、あらゆるバリエーションで全コストがかかる | E2E の経路は 1 つに保ち、バリエーションは下位レイヤーに移す |
| E2E テストのみでサービス境界をテスト | コストが高く、壊れやすい | コンシューマー主導の契約テストを追加する |
| テスト内のロジック | テスト自体が、検出すべきバグを抱える可能性がある | ハードコードした期待値を使い、制御フローを含めない |
| カバレッジを品質とみなす | カバレッジが高くても、アサーションが弱い場合がある | カバレッジで不足箇所を見つけ、ミューテーションテスト/契約テストで強度を検証する |
| 本番環境のフィードバックループがない | 既知でない障害モードが見えないまま残る | 可観測性、合成モニタリング、探索的テストを追加する |
| レガシーコードのテストを省略する | リファクタリング中にリスクが高まる | 振る舞いを変更する前に、特性を記録するテスト網を構築する |
| AI エージェントが自分のコードをテストする | テストがバグを仕様化してしまう | テスト作成者とコーダーの役割を分ける |
| エージェントが合格するよう受け入れテストを弱める | セーフガードが無効化される | コーディングエージェントが受け入れテストを変更できないようにする |
| アーキテクチャルールを振る舞いとしてテストする | 構造上のルールはユーザーに見える振る舞いではない | 静的解析でアーキテクチャを適用し、観測可能な結果をテストする |
統合例
変更前 — テストしにくい(問題は設計にあります):
function sendOverdueReminders() {
const users = db.query("SELECT * FROM users WHERE balance < 0");
for (const user of users) {
if (Date.now() - user.lastReminded > WEEK) {
emailClient.send(user.email, "You owe us money");
}
}
}
この関数をテストするには、データベース、時計、メールクライアントを制御する必要があります。ビジネスルールである 誰にリマインダーを送るべきか は、副作用の中に埋もれています。
診断: I/O を境界に移し、ルールを純粋に保ちます。
変更後 — 純粋なコアと境界の I/O:
function usersToRemind(users, now) {
return users.filter(
(user) => user.balance < 0 && now - user.lastReminded > WEEK,
);
}
function sendOverdueReminders() {
for (const user of usersToRemind(db.allUsers(), Date.now())) {
emailClient.send(user.email, "You owe us money");
}
}
usersToRemind([...], fixedNow) は、ダブルを使わずに 1 行で書けるユニットテストです。残るシェルは薄い統合上の懸念事項です。モックを追加したのではなく、設計を変更することで、テストしにくいものをテストしやすくしました。
必要に応じて読む
| 次の場合に読む | ファイル |
|---|---|
| 4 つの横断的なテスト原則を理解する場合 | テスト原則 |
| 12 の望ましい特性に照らしてテスト品質を監査する場合 | TestDesiderata — 品質監査 |
| BDD への準拠と構成についてテストをレビューする場合 | BDD テストレビュー |
| AI コーディングエージェントに指示する場合:頻度、パイプライン、信頼モデル | AI コーディングエージェントによるテスト |
| 何をモックし、何をアサートするかを選ぶ場合 | モックと脆弱性 |
| 信頼性、保守性、可読性を監査する場合 | 信頼性と保守性に優れたテスト |
| テストレイヤー間でシナリオを分配する場合、テストレシピ、レガシーコードのトリアージ | テスト戦略とレガシーコード |
| 非同期コード、タイマー、イベント、モジュールのフェイクをテストする場合 | 非同期処理、時間、モジュールのフェイク |
| Fowler 流のポートフォリオ、テストダブル、本番環境からのフィードバック、LLM の実践を適用する場合 | Martin Fowler のテストの規範 |
| CI ゲート用のスモークテスト(Hurl または curl)を特定して作成する場合 | スモークテスト |
| green での自動コミットと失敗時の自動リバートを伴う red/green/refactor(TCR/TCRDD) | TCRDD |
| Given/When/Then シナリオで振る舞いを導き、crap とミューテーションの品質ゲートを適用する場合 | 受け入れテストのワークフロー |
| テストスタイル、関数型コア、モックの境界、DB テスト、アンチパターン(Khorikov) | ユニットテストの原則 |
| テストファーストのリズム:フェイク、三角測量、テスト可能な設計、受け入れ TDD(Koskela) | TDD と ATDD |
| Web API のテスト:リスクベースのチェック、コントラクト、パフォーマンス、セキュリティ、SLO | Web API テスト |
| Arrange-Act-Assert、モックオブジェクト、c2 wiki の TDD に関するメモ | XP のテストプラクティス |
ベンチマーク
シナリオ:.benchmarks/scenarios/testing-001-agent-test-strategy.md · 実行日:2026-08-31 · ログ:.benchmarks/runs/2026-08-31/testing-001-agent-test-strategy.json
| モデル | なし | あり | 差分 |
|---|---|---|---|
| claude-opus-4-8 | 67% | 100% | +33% |
| claude-sonnet-4-6 | 100% | 100% | +0% |
| claude-haiku-4-5 | 67% | 100% | +33% |
合格(実行日 2026-08-31)。Opus と haiku は +33、sonnet は上限に到達しています。ゲートは
.agents/skills/skill-optimizer/rules/release-gates.mdに従います。