70

FileField を持つモデルがあります。単体テストしたい。django テスト フレームワークには、データベースと電子メールを管理する優れた方法があります。FileFields に似たものはありますか?

単体テストが実際のアプリケーションを汚染しないようにするにはどうすればよいですか?

前もって感謝します

PS: 私の質問は、テスト フィクスチャを使用した Django テスト FileFieldのほぼ複製ですが、受け入れられた回答がありません。このトピックについて何か新しいことがあるかどうかをもう一度尋ねたいだけです。

4

5 に答える 5

122

Django はこれを行う優れた方法を提供します - aSimpleUploadedFileまたは aを使用しTemporaryUploadedFileます。SimpleUploadedFile保存する必要があるのがセンチネルデータだけである場合、一般的にはより簡単なオプションです。

from django.core.files.uploadedfile import SimpleUploadedFile

my_model.file_field = SimpleUploadedFile(
    "best_file_eva.txt",
    b"these are the file contents!"   # note the b in front of the string [bytes]
)

これは、ドキュメントに表示されないdjangoの魔法の機能の1つです:)。ただし、ここで参照され、ここで実装されます

制限事項

舞台裏を使用して実装されているためbytes、 aのみを入れることができることに注意してください。より現実的なファイルのような動作が必要な場合は、.SimpleUploadedFileBytesIOTemporaryUploadedFile

Python 2 の場合

Python 2 で行き詰まっている場合bは、コンテンツ内のプレフィックスをスキップしてください。

my_model.file_field = SimpleUploadedFile(
    "best_file_eva.txt",
    "these are the file contents!" # no b
)
于 2013-12-11T01:06:30.290 に答える
50

これに取り組む方法はいくつかありますが、単体テストは分離されているはずですが、ファイルは永続的な変更に関するものであるため、それらはすべて醜いものです。

私の単体テストは、本番データを含むシステムでは実行されないため、実行するたびにアップロード ディレクトリを簡単にリセットできgit reset --hardます。このアプローチは、コードの変更を必要とせず、適切なテスト データを使用して開始する限り動作することが保証されているという単純な理由から、いくつかの点で最適です。

モデルの save メソッドをテストした後、実際にそのファイルで何もする必要がない場合は、Python の優れたMock ライブラリを使用してインスタンスを完全に偽造することをお勧めしFileます (つまり、 のようなものmock_file = Mock(spec=django.core.files.File); mock_file.read.return_value = "fake file contents")。これにより、ファイル処理ロジックの変更を完全に回避できます。 . Mock ライブラリには、テスト メソッド内でDjango のFile クラスにグローバルにパッチを適用する方法がいくつかありますが、これは非常に簡単です。

実際のファイルが必要な場合 (つまり、テストの一部として機能するため、外部スクリプトで処理するためなど)、Mirko の例に似たものを使用して、適切な場所に保存されていることを確認した後にFile オブジェクトを作成できます。 - これを行うには、次の 3 つの方法があります。

  • テストsettings.MEDIA_ROOTが一時ディレクトリを指すようにします (Python tempfileモジュールのmkdtemp関数を参照してください)。STATIC_ROOTソースコードの一部であるメディアファイルに使用する別のようなものがある限り、これはうまく機能します。
  • カスタムストレージ マネージャーを使用する
  • 各 File インスタンスでファイル パスを手動で設定するか、カスタムのupload_to関数を使用して、テストのセットアップ/ティアダウン プロセスが削除する場所 (.ini の下のテスト サブディレクトリなど) を指定しMEDIA_ROOTます。

編集:モック オブジェクト ライブラリは、python バージョン 3.3 で新しく追加されました。古い python バージョンについては、Michael Foord のバージョンを確認してください

于 2010-12-28T15:41:35.053 に答える
15

私は通常、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" に置き換えます。
あとは、必要なファイルを含む test フォルダーを test setUp の "audio" にコピーし、tearDown で削除するだけです。

私が考える最もクリーンな方法ではありませんが、それが私がしていることです。

于 2010-11-26T17:08:04.343 に答える
3

FileField を必要とするオブジェクトを作成したいだけで、このフィールドを使用したくない場合は、次のように任意の (存在するかどうかに関係なく) 相対パスを渡すことができます。

example_object = models.ExampleModel({'file': "foo.bar"})
example_object.save()

その後、使用する準備が整いました。

于 2012-03-16T14:03:52.727 に答える