私は大規模なDjangoプロジェクトの効果的な単体テストを書くのに本当に苦労しています。私はかなり良いテストカバレッジを持っていますが、私が書いてきたテストは間違いなく統合/受け入れテストであり、ユニットテストではないことに気付きました。これをできるだけ早く修正したいと思います。
これが私の問題です。私のスキーマは深いリレーショナルであり、非常に時間指向であり、モデルオブジェクトに高い内部結合と多くの状態を与えます。私のモデルメソッドの多くは、時間間隔に基づいてクエリを実行auto_now_add
し、タイムスタンプ付きのフィールドで多くのことを行っています。したがって、たとえば次のようなメソッドを使用します。
def summary(self, startTime=None, endTime=None):
# ... logic to assign a proper start and end time
# if none was provided, probably using datetime.now()
objects = self.related_model_set.manager_method.filter(...)
return sum(object.key_method(startTime, endTime) for object in objects)
このようなものをテストする方法はありますか?
ここに私がここにいます。ユニットテストの目的には、その引数にいくつかの模擬動作を与える必要がありますが、正しい結果を生成するために正しくフィルタリング/集計されていますか?by key_method
summary
datetime.now()のモックは簡単ですが、残りの動作をどのようにモックできますか?
- フィクスチャを使用することもできますが、データを構築するためにフィクスチャを使用することの長所と短所を耳にしました(保守性が悪いことは、私にとっては当たり前のことです)。
- ORMを使用してデータを設定することもできますが、関連するオブジェクトも作成する必要があるため、制限される可能性があります。また、ORMでは、
auto_now_add
フィールドを手動で変更することはできません。 - ORMのモックは別のオプションですが、深くネストされたORMメソッドをモックするのが難しいだけでなく、ORMコードのロジックがテストからモックされるため、モックはテストをテストの内部と依存関係に本当に依存させるようですテスト対象機能。
クラックするのが最も難しいのは、このような関数であると思われます。これらの関数は、モデルのいくつかの層と下位レベルの関数にあり、これらの関数は非常に複雑ではないかもしれませんが、時間に非常に依存しています。私の全体的な問題は、どのようにスライスしたように見えても、テストはテストしている機能よりもはるかに複雑に見えることです。