testing-anti-patterns について
テストの作成、変更、レビューを行う開発者向けのスキルです。モックではなく実際のコードの動作を検証する方針を軸に、モックの不足やテスト専用メソッドなどの問題を避ける方法を示します。
主な機能
- 01モックではなく実際の動作を検証
- 02本番コードへのテスト専用メソッド追加を回避
- 03依存関係を理解してモック化
- 04完全なモックの維持
- 05TDD による問題の予防
活用シーン
- 01モック呼び出しを検証するテストのレビュー
- 02依存関係をモック化する必要性の判断
- 03不足しているモックデータの発見
- 04テストを後回しにする習慣の防止
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ bobmatnyc/ claude-mpm-skills --skill testing-anti-patternsインストール後、Claude Code で/testing-anti-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonreferences/completeness-anti-patterns.mdcore-anti-patterns.mddetection-guide.mdpython-examples.mdtdd-connection.md詳細
テストのアンチパターン
概要
テストでは、モックの振る舞いではなく、実際の振る舞いを検証する必要があります。モックはテスト対象ではなく、分離するための手段です。
基本原則: モックの振る舞いではなく、コードの動作をテストします。
厳格な TDD に従うことで、これらのアンチパターンを防げます。 TDD ワークフローの全容については、テスト駆動開発スキル(スキルライブラリで利用可能)をご覧ください。
このスキルを使うタイミング
次のような場合に、このスキルを有効にします:
- テストを作成または変更するとき - テストが実際の振る舞いをカバーしているか確認します
- モックを追加するとき - モックが必要であり、正しく使われているか確認します
- テストの失敗を調査するとき - モックの振る舞いが問題かどうか確認します
- テスト専用メソッドを追加したくなったとき - いったん止まり、再検討します
- テストが複雑すぎると感じるとき - モックの使いすぎの兆候です
鉄の掟
1. NEVER test mock behavior
2. NEVER add test-only methods to production classes
3. NEVER mock without understanding dependencies
4. NEVER create incomplete mocks
5. NEVER treat tests as afterthought
主なアンチパターンのカテゴリ
1. モックの振る舞いをテストする
実際の振る舞いではなく、モックの要素を検証します。対処法: 実際のコンポーネントをテストするか、モックを使わないようにします。 → core-anti-patterns.md
2. 本番コードにテスト専用メソッドを追加する
本番クラスにあり、テストでしか使われないメソッドです。対処法: テストユーティリティに移します。 → core-anti-patterns.md
3. 理解せずにモックを使う
依存関係や副作用を理解せずにモックを使います。対処法: まず理解し、モックは最小限にします。 → core-anti-patterns.md
4. 不完全なモック
後続のコードで必要となるフィールドが欠けた部分的なモックです。対処法: API の構造全体を反映させます。 → completeness-anti-patterns.md
5. 後回しにされるテスト
テストがないまま、実装を「完了」とします。対処法: TDD に従い、最初にテストを書きます。 → completeness-anti-patterns.md
すばやく見つけるためのチェックリスト
テストをコミットする前に、このチェックリストを実行します:
言語に依存しない確認項目:
□ Am I asserting on mock behavior instead of real behavior?
→ TypeScript: testId='*-mock', expect(mock).toHaveBeenCalled()
→ Python: mock.assert_called(), mock.call_count
→ If yes: STOP - Test real behavior or unmock
□ Does this method only exist for tests?
→ TypeScript: destroy(), reset(), clear() only in *.test.ts
→ Python: _set_mock_*, _for_testing only in test_*.py
→ If yes: STOP - Move to test utilities
□ Do I fully understand what I'm mocking?
→ If no: STOP - Run with real impl first, then mock minimally
□ Is my mock missing fields the real API has?
→ TypeScript: Partial<T>, incomplete objects
→ Python: Mock() with few attributes, missing nested fields
→ If yes: STOP - Mirror complete API structure
□ Did I write implementation before test?
→ If yes: STOP - Delete impl, write test first (TDD)
□ Is mock setup >50% of test code?
→ If yes: Consider integration test with real components
参照: 危険信号や警告の兆候について詳しくは、detection-guide.mdをご覧ください。
要点
モックは分離のためのツールであり、テスト対象ではありません。
モックの振る舞いをテストしている場合は、問題があることを示しています。対処法:実際の振る舞いをテストするか、そもそもモックが必要なのかを問い直します。
TDD はこれらのパターンを防ぎます。 最初にテストを書く → 失敗することを確認する → 最小限の実装を行う → 成功させる → リファクタリングする。
ナビゲーション
アンチパターンの詳細な分析
- 主なアンチパターン - パターン1〜3:モックの振る舞い、テスト専用メソッド、理解不足のまま行うモック
- 完全性に関するアンチパターン - パターン4〜5:不完全なモック、後回しにされるテスト
検出と予防
言語別の例
- Python の例 - 5つのアンチパターンすべてを扱う、unittest.mock と pytest-mock のパターン、フィクスチャのベストプラクティス、pytest 固有の検出方法を含む Python/pytest の完全ガイドです。Python のテストを扱う場合に読み込んでください。
関連スキル
このスキルを使用する際は、次の補完スキルも検討してください(スキルバンドルに含まれている場合)。
-
test-driven-development:TDD の完全なワークフローと、レッド・グリーン・リファクタリングのサイクル
- ユースケース:アンチパターンを防ぐために、TDD の規律を実践する
- 連携:TDD ワークフローにより、ほとんどのアンチパターンを設計上防止できます
- ステータス:推奨 — 基本的なアンチパターンはこのスキルで扱っています
-
verification-before-completion:「完了」の定義と検証プロトコル
- ユースケース:完了条件にテストが含まれていることを確認する
- 連携:作業を完了と見なす前に、テストに合格する必要があります
- ステータス:推奨 — テストを重視する姿勢を強化します
注:すべてのスキルは個別にデプロイできます。このスキルは、ほかのスキルがなくても完全に機能します。
主な注意事項
- モックは分離するためのものであり、証明するためのものではありません — モックではなく、実際のコードをテストしてください
- 本番コードはテストを無視します — テスト専用のメソッドは作成しないでください
- モックを作成する前に理解してください — 依存関係と副作用を把握してください
- 完全なモックのみを使用してください — API 構造全体を反映させてください
- テストも実装の一部です — 後回しにしてよいものではありません
危険信号 — 作業を中止
次の場合は、直ちに作業を中止してください。
- モックの動作をテストしている
- TypeScript:
*-mockテスト ID に対するアサーション、expect(mock).toHaveBeenCalled() - Python:実際の動作を確認せずに、
mock.assert_called()やmock.call_countを使用している
- TypeScript:
- テスト専用のメソッドを追加している
- TypeScript:
*.test.tsにしかないdestroy()やreset() - Python:「For testing only」という docstring を付けた
_set_mock_*や_for_testing
- TypeScript:
- 理解せずにモックを作成している
- 「念のため」と
@patchやvi.mock()を追加している - API ドキュメントではなく、記憶を頼りにモックを作成している
- 「念のため」と
- 不完全なモック
- TypeScript:
Partial<T>を使用している、ネストしたオブジェクトが欠けている - Python:データオブジェクトに
Mock()を使用している、必須フィールドが欠けている
- TypeScript:
- テストを後回しにしている
- 「テストは後でよい」や「テストする準備ができた」と言っている
- テストのコミットより先に実装をコミットしている
モックが複雑になりすぎた場合: 実際のコンポーネントを使った結合テストを検討してください。多くの場合、そのほうがシンプルで有益です。
他のスキルとの連携
前提条件: Test-Driven Development スキル — TDD はアンチパターンを防ぎます(完全なワークフローには推奨) 補完スキル: Verification-Before-Completion スキル — テストが完了を意味します(適切なテストの規律を確保) ドメイン固有: フレームワークのパターンについては、webapp-testing と backend-testing を参照してください(利用可能な場合はスキルライブラリを確認してください)