あなたはあなた自身の質問に答えたと思います。制御の反転や依存性注入など、Web フレームワークのテストに使用するものと同じことが Django にも適用されます。Python では非常にシンプルに保つことができるので、たとえば Spring などに存在するものに怯えたり、興味をそそられたりしないでください。
クラスベースのビューからコードを移動してみませんか? 何らかの理由で他の場所で同じロジックが必要な場合、コードはまだ DRY にはなりません。Django だからといって、優れたプログラミング原則が適用されないわけではありません。
サービス (Django のサービス定義ではなく概念として) などの新しいクラス/Python モジュールや、データ アクセスのためのその他の論理抽象化でいくつかのものを抽象化することをお勧めします。これにより、Django ビューのリクエスト/レスポンス ライフサイクルから完全に独立します。Django と Rails の開発者は、すべてのロジックをモデルまたはビューに直接配置する傾向があります。これは、神のクラスやテストが難しいものにつながるだけです。
ビューを、マーシャリング パラメータ (GET/POST) などをコードの残りの部分に処理し、別の場所にカプセル化された必要なロジックを呼び出す軽い抽象化と考えることで、これを容易にすることもできます。IMO、テスト可能なコードが必要な場合、プロセスにとって絶対に重要でない限り、ロジックの 99% は Web コンテキストの外にある必要があります。これにより、バックグラウンドでの並列実行も容易になります。
最終的に得られるのは、HTTP に直接依存していないため、テストが容易な通常の python モジュールとクラスです。HTTP をモックする必要がある場合は、単にリクエスト オブジェクトをモックできます。幸いなことに、python/django の組み合わせにより、これらのものを単純な dict/kwargs として簡単にダンプしてモックできます。
クラスベースのビューを使用して気づいたことの 1 つは、ミックスインで使用し、いくつかの規則 (json を返す、グラフのプロパティを開くなど) を適用するのに適していることですが、DetailView などのモデルを直接必要とするより「高度な」クラスベースのビューを使用するだけです。不必要に物事を複雑にします。これらのビューは、管理画面には適していますが、実際のアプリにとっては害以上の助けになります。キャッシュレイヤーなどを統合するための優れたシームレスな方法を見つけない限り、テストが難しくなり、パフォーマンスが低下します。この時点で、通常は View または TemplateView から継承して、それで完了です。
特に DB モッキングに関しては、モックを作成し、ビジネス ロジックを調べます。次に、特定のルールとインターフェースのセットに準拠している限り、何を入力/出力しているかは問題ではありません。たとえば、 Mixerのようなものを参照してください。テスト中に一時 DB を作成/破棄することもできます。1 つの方法は、dev/staging/production/testing などの個別の設定モジュールを作成し、環境に応じて動的にロードすることです。そうすれば、単体テストを実行するときに、作業中の開発データベースが損傷するのを防ぐことができます。もちろん、これは統合テストの形式にさらに移行していますが、おそらくその一部も行う必要があります。前述のソリューションは、Hibernate などの他の ORM で一般的です。
前に関連して、設定で以下のコードのようなことを実行して、単体テストにメモリ内データベースを使用できます。ただし、最終的には、MySQL などの実際のデータ ストア タイプに対する統合テストを検討する必要があります。
if 'test' in sys.argv:
DATABASES['default']['ENGINE'] = 'sqlite3'
;tldr
ロジックをクラス ビューの外に配置し、適切なオブジェクトとモジュールに配置します。
バンドルされているさまざまなクラスベースのビューを、実際のアプリやすべてのユース ケースで機能させることに固執しないでください。自分で巻きます。
IOC などの一般的に適切な TDD 原則を使用し、必要なパラメーターをコンストラクターに渡し、物事を疎結合し、過剰な独自の状態要件 (特に HTTP) を回避します。
- 標準のモック オブジェクトを作成し (#3 を参照)、サービスのようなインターフェイスを使用することで (#1 を参照)、DB への依存を回避します。