mcpField
P
pytest-django-patterns

pytest-django-patterns

github.com/waldencuiテスト・品質17855 回インストール32 週間前に更新
リポジトリ

pytest-django-patterns について

Djangoプロジェクトの開発者向けpytest-djangoテストガイドです。テストを先に書く開発を重視し、データベース、ビュー、フォーム、モデル、タスクのテスト方法を扱います。

主な機能

  1. 01RED-GREEN-REFACTORの手順
  2. 02データベースマーカーとファクトリー
  3. 03アプリ単位のテスト構成
  4. 04ビュー・フォーム・モデルのテスト
  5. 05外部サービスとタスクのモック

活用シーン

  1. 01機能開発でテスト駆動開発を実践
  2. 02HTMXビューと権限の動作確認
  3. 03フォーム検証とデータベース変更の検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/waldencui/claude-code-django --skill pytest-django-patterns

インストール後、Claude Code で/pytest-django-patternsを入力して読み込まれたか確認します。

詳細

pytest-django のテストパターン

TDD ワークフロー(RED-GREEN-REFACTOR)

常に次のサイクルに従ってください。

  1. RED:期待する動作を記述した失敗するテストを最初に書きます
  2. GREEN:テストを通過させるための最小限のコードを書きます
  3. REFACTOR:テストを通過させたままコードを整理します
  4. REPEAT:失敗するテストなしに本番コードを書いてはいけません

重要なルール:機能を実装したりバグを修正したりする場合は、本番コードに手を加える前にテストを書いてください。

pytest-django の基本的なパターン

データベースアクセス
  • データベースにアクセスするテストには、@pytest.mark.django_db を使います
  • モジュール全体に適用します:pytestmark = pytest.mark.django_db
  • 各テストの後にトランザクションは自動的にロールバックされます
テストデータ用のフィクスチャ

モデルには Factory Boy を、セットアップには pytest のフィクスチャを使います。

  • ファクトリー:現実的なデータでモデルインスタンスを作成します(UserFactory())

    • 一意なフィールドには factory.Sequence() を使います
    • 現実的なダミーデータには factory.Faker() を使います
    • 外部キーには factory.SubFactory() を使います
    • M2M リレーションシップには @factory.post_generation を使います
  • フィクスチャ:クライアント、認証状態、共有リソースをセットアップします

    • client フィクスチャ:Django のテストクライアント
    • auth_client フィクスチャを作成します:認証済みのリクエストには client.force_login(user) を使います
    • テストファイル間で再利用できるよう、conftest.py に定義します
テストの構成

テストをアプリの構成に合わせて配置します。

tests/
├── apps/
│   └── posts/
│       ├── test_models.py
│       ├── test_views.py
│       └── test_forms.py
├── factories.py
└── conftest.py

関連するテストをクラスにまとめます。

  • クラス名は TestComponentName にします(例:TestPostListView)
  • テストメソッドには内容が分かる名前を付けます:test_<action>_<expected_outcome>
  • 複数のシナリオをテストするには @pytest.mark.parametrize を使います

テスト対象

ビュー
  • ステータスコード:正しい HTTP レスポンス(200、404、302)
  • 認証:認証済みと匿名の場合の動作
  • 認可:ユーザーが自分のデータにのみアクセスできること
  • コンテキストデータ:テンプレートに正しいオブジェクトが渡されること
  • 副作用:データベースの変更、メール送信、タスクのキュー登録
  • HTMX:HTTP_HX_REQUEST ヘッダーによって部分テンプレートが返されることを確認します
フォーム
  • バリデーション:有効なデータは通過し、無効なデータは正しいエラーで失敗すること
  • エッジケース:空のフィールド、最大長、一意性制約
  • Clean メソッド:カスタムバリデーションロジックが機能すること
  • 保存時の動作:オブジェクトが正しく作成・更新されること
モデル
  • メソッド:__str__ やカスタムメソッドが期待される値を返すこと
  • マネージャー/クエリーセット:カスタムフィルタリングが正しく機能すること
  • 制約:データベースレベルのバリデーションが適用されること
  • シグナル:保存前/保存後のフックが正しく実行されること
Celery タスク
  • 外部呼び出しをモックする:HTTP リクエスト、メール送信などをパッチします
  • ロジックのみをテストする:実際の非同期実行はテストしません
  • 冪等性:タスクを複数回実行しても安全であること

Django 固有のテストパターン

HTMX レスポンスのテスト

HX-Request ヘッダーが存在するときに部分テンプレートがレンダリングされることを確認します。

  • クライアントリクエストに HTTP_HX_REQUEST="true" を渡します
  • response.templates に部分テンプレート名が含まれることをアサートします
権限のテスト

認証済みクライアントと匿名クライアントのフィクスチャを作成します。

  • 未認可のアクセスに対するリダイレクト/403 をテストします
  • 認可されたアクセスが成功することをテストします
クエリーセットのテスト

効率的なクエリーを確認します。

  • ファクトリーでテストデータを作成します
  • クエリーを実行します
  • 正しいオブジェクトが返される/除外されることをアサートします
  • select_related()/prefetch_related() で関連オブジェクトが読み込まれることを確認します
モデルインスタンスを使ったフォームのテスト

更新時にはインスタンスをフォームに渡します。

  • form = MyForm(data=new_data, instance=existing_obj)
  • form.save() が新規作成ではなく更新することを確認します

共通パターン

複数のシナリオをパラメーター化する: さまざまな入力をテストするには、@pytest.mark.parametrize("input,expected", [...]) を使用します

外部サービスをモックする: 実際の HTTP 呼び出し、メール送信、ファイル操作を避けるには、mocker.patch() を使用します

データベースの変更を確認する:

  • 作成後に Model.objects.filter(...).exists() をアサートします
  • 削除後に Model.objects.count() == expected をアサートします
  • 更新を確認するには refresh_from_db() を使用します

エラー処理をテストする:

  • 無効なフォームデータで正しいエラーが発生すること
  • 失敗した操作がエラーレスポンスを返すこと
  • ユーザーに適切なエラーメッセージが表示されること

テストの実行

uv run pytest                    # All tests
uv run pytest -x                 # Stop on first failure
uv run pytest --lf               # Run last failed
uv run pytest -x --lf            # Stop first, last failed only
uv run pytest -k "test_name"     # Run tests matching pattern
uv run pytest tests/apps/posts/  # Specific directory
uv run pytest --cov=apps         # With coverage report

よくある落とし穴

  • @pytest.mark.django_db を付け忘れる:「Database access not allowed」エラーが発生します
  • ファクトリーを使用しない:インスタンスを手動で作成すると、冗長で壊れやすくなります
  • 実装をテストする:内部の実装詳細ではなく、動作と結果をテストします
  • TDD を省略する:コードの後にテストを書くと、テストが実装に追従し、エッジケースを見落とします
  • モックを使いすぎる:外部依存関係をモックし、自分のコードはモックしないでください
  • フレームワークのコードをテストする:Django の ORM やフォームのバリデーションなどはテストしないでください。独自のロジックをテストします

セットアップ要件

pyproject.toml 内:

[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "config.settings.test"
python_files = ["test_*.py"]
addopts = ["--reuse-db", "-ra"]

conftest.py 内: 共有フィクスチャ(auth_client、共通のファクトリーなど)を定義します

他のスキルとの連携

  • systematic-debugging:バグを修正するときは、再現するために最初に失敗するテストを書きます
  • django-models:カスタムマネージャー、QuerySet、モデルメソッドをテストします
  • django-forms:フォームのバリデーション、clean メソッド、保存時の動作をテストします
  • celery-patterns:外部依存関係をモックしてタスクのロジックをテストします

コメント