FileFieldを持つモデルがあります。単体テストしたい。 Djangoテストフレームワークには、データベースと電子メールを管理する優れた方法があります。FileFieldsにも同様のものはありますか?
ユニットテストが実際のアプリケーションを汚染しないことを確認するにはどうすればよいですか?
前もって感謝します
PS:私の質問はほぼ テストフィクスチャを使用したDjangoテストFileField の複製ですが、承認された回答がありません。このトピックについて何か新しいことがあれば、もう一度質問してください。
これに対処する方法はいくつかありますが、単体テストは分離されているはずなのでファイルはすべて永続的な変更に関するものなので、すべて醜いです。
私の単体テストは本番データのあるシステムでは実行されないので、各実行後に_git reset --hard
_のようなものでアップロードディレクトリをリセットするのは簡単です。このアプローチは、コードの変更を含まず、優れたテストデータで作業を開始する限り機能することが保証されているという理由で、いくつかの点で最良です。
モデルのsaveメソッドをテストした後、実際にそのファイルで何もする必要がない場合は、pythonの優れた Mock library を使用してFile
インスタンス(つまり、何か)を完全に偽造することをお勧めしますmock_file = Mock(spec=Django.core.files.File); mock_file.read.return_value = "fake file contents"
)のように、ファイル処理ロジックへの変更を完全に回避できます。 Mockライブラリには、テストメソッド内で globally patch Djangoの File class を実行する方法がいくつかあります。
実際のファイルが必要な場合(つまり、テストの一部として使用する場合、外部スクリプトで処理する場合など)、Mirkoの例に似たものを使用して、確認後に Fileオブジェクト を作成できます。適切な場所に保存されます-これを行う3つの方法を次に示します。
settings.MEDIA_ROOT
_が一時ディレクトリを指すようにします(Python tempfile モジュールのmkdtemp
関数を参照)。これは、ソースコードの一部であるメディアファイルに使用する別の_STATIC_ROOT
_のようなものがあります。MEDIA_ROOT
_の下のテストサブディレクトリなど)を指定します。編集:モックオブジェクトライブラリがpythonバージョン3.3で新しく追加されました。古いpython =バージョンチェック Michael Foordのバージョン
Djangoはこれを行うための優れた方法を提供します-SimpleUploadedFileを使用します。
from Django.core.files.uploadedfile import SimpleUploadedFile
my_model.file_field = SimpleUploadedFile('best_file_eva.txt', 'these are the file contents!')
これは、Djangoの魔法の機能の1つです。ただし、それは here と呼ばれます。
私は通常、doctestを使用してモデルのファイルフィールドをテストします
>>> from Django.core.files import File
>>> s = SimpleModel()
>>> s.audio_file = File(open("media/testfiles/testaudio.wav"))
>>> s.save()
>>> ...
>>> s.delete()
必要な場合は、テストクライアントでファイルのアップロードもテストします。
フィクスチャについては、フィクスチャのパスを変更した後、必要なファイルをテストフォルダーにコピーするだけです。
例えば.
「audio」という名前のディレクトリを指すファイルフィールドを持つモデルを含むフィクスチャでは、「audio」:「audio/audio.wav」を「audio」:「audio/test/audio.wav」に置き換えます。
今必要なのは、必要なファイルを含むテストフォルダーを、テストセットアップの「オーディオ」にコピーし、それをティアダウンで削除することだけです。
これまで考えた中で最もクリーンな方法ではありませんが、それが私のやり方です。
オブジェクトを作成する FileFieldとこのフィールドを使用したくないを必要とする場合は、次のような相対パス(既存または非存在)を渡すだけです。
self.example_object = models.ExampleModel({'file': "foo.bar"})
self.example_object.save()
これで使用できるようになります。