2010-11-26 1 views
33

У меня есть модель с FileField. Я хочу это сделать. В платформе django test есть отличные способы управления базами данных и электронной почтой. Есть ли что-то подобное для FileFields?Что такое чистый способ unittest FileField в django?

Как я могу убедиться, что unittests не загрязнят реальное приложение?

Заранее спасибо

PS: Мой вопрос почти дубликат Django test FileField using test fixtures, но он не имеет общепринятый ответ. Просто хочу спросить, есть ли что-то новое в этой теме.

+1

Возможный дубликат [Django test FileField с использованием тестовых приспособлений] (http://stackoverflow.com/questions/2266503/django-test-filefield-using-test-fixtures) – waterproof 2016-07-15 00:57:25

ответ

31

Существует несколько способов решения этой проблемы, но все они уродливы, поскольку модульные тесты должны быть изолированы, но файлы - все о долговременных изменениях.

Мои модульные тесты не запускаются в системе с производственными данными, поэтому было легко просто сбросить каталог загрузки после каждого запуска с чем-то вроде git reset --hard. Этот подход в лучшем случае просто потому, что он не требует изменений кода и гарантированно работает до тех пор, пока вы начинаете с хороших тестовых данных.

Если вы на самом деле не нужно ничего делать с этим файлом после тестирования метода сохранения вашей модели, я бы рекомендовал использовать Майкл Фурд отличный Mock library полностью подделать File экземпляра (то есть что-то вроде mock_file = Mock(spec=django.core.files.File); mock_file.read.return_value = "fake file contents"), так что вы можете полностью избежать изменения в логике обработки файлов. Библиотека Mock имеет несколько способов: globally patch Django's File class в методе тестирования, который примерно так же прост, как это получится.

Если у вас есть реальный файл (т. Е. Для участия в тестировании, обработка внешним скриптом и т. Д.), Вы можете использовать что-то похожее на пример Мирко и создать File object, убедившись, что это будет хранится где уместно - вот три способа сделать это:

  • Имейте свою точку тест settings.MEDIA_ROOT во временную директорию (см mkdtemp функции модуля Python tempfile). Это прекрасно работает, если у вас есть что-то вроде отдельного STATIC_ROOT, которое вы используете для медиафайлов, которые являются частью вашего исходного кода.
  • Использование пользовательских storage manager
  • указан путь к файлу вручную на каждом экземпляре файла или иметь пользовательскую функцию upload_to указать где, какие ваши настройки тестирования/Teardown процесса чистки, такие как тест подкаталог MEDIA_ROOT.
+0

Спасибо за этот отличный ответ. Я, наконец, решил указать на unit-test MEDIA_ROOT, изменив значение этой переменной в setUp моего тестового примера. – luc 2010-12-30 07:24:49

10

Я обычно проверить filefields в моделях с использованием 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».
Теперь все, что вам нужно сделать, это скопировать тестовую папку с необходимыми файлами в «audio» в test setUp и затем удалить ее в tearDown.

Не самый чистый путь, когда-либо я думаю, но это то, что я делаю.

+0

Как это сделать с помощью ImageField ?? ? – 2014-10-10 19:09:48

+0

Должен ли я вручную закрыть дескриптор файла, чтобы освободить ресурсы, используемые им? – Pieter 2017-02-03 10:21:57

0

Если вы просто хотите создать объект, который требует FileField и не хотите использовать это поле, то вы можете просто передать любой (существующий или нет) относительный путь, как это:

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

Затем он готов к использованию.

58

Django предоставляет отличный способ сделать это - используйте SimpleUploadedFile.

from django.core.files.uploadedfile import SimpleUploadedFile 

my_model.file_field = SimpleUploadedFile('best_file_eva.txt', 'these are the file contents!') 

Это одна из магических черт-это-не-шоу-вверх-в докторантов Джанго :). Однако он относится к here.

Смежные вопросы