you template tag simple register name forget examples example did python django filefield django-unittest

python - template - ¿Cuál es la forma limpia de unitfest FileField en django?



simple upload file django (4)

Django proporciona una excelente manera de hacer esto: use un archivo SimpleUploadedFile.

from django.core.files.uploadedfile import SimpleUploadedFile my_model.file_field = SimpleUploadedFile(''best_file_eva.txt'', ''these are the file contents!'')

Es una de las características mágicas de django que no se muestran en la documentación :). Sin embargo, se hace referencia here .

Tengo un modelo con un FileField. Quiero probarlo. El marco de prueba de Django tiene excelentes maneras de administrar bases de datos y correos electrónicos. ¿Hay algo similar para FileFields?

¿Cómo puedo asegurarme de que las pruebas de unidad no contaminen la aplicación real?

Gracias por adelantado

PD: Mi pregunta es casi un duplicado del campo de prueba de Django usando dispositivos de prueba, pero no tiene una respuesta aceptada. Solo quiero volver a preguntar si hay algo nuevo sobre este tema.


Hay varias maneras de abordar esto, pero todas son feas, ya que se supone que las pruebas unitarias están aisladas, pero los archivos se tratan de cambios duraderos.

Mis pruebas de unidad no se ejecutan en un sistema con datos de producción, por lo que es fácil simplemente restablecer el directorio de carga después de cada ejecución con algo como git reset --hard . Este enfoque es, en cierto modo, el mejor simplemente porque no implica cambios de código y se garantiza que funcionará siempre que comience con buenos datos de prueba.

Si realmente no necesita hacer nada con ese archivo después de probar el método de guardado de su modelo, recomiendo usar la excelente biblioteca Mock de Python para falsificar completamente la instancia del File (es decir, algo como mock_file = Mock(spec=django.core.files.File); mock_file.read.return_value = "fake file contents" ) para que pueda evitar por completo los cambios en su lógica de manejo de archivos. La biblioteca de simulacros tiene un par de formas para parchear globalmente la clase de archivos de Django dentro de un método de prueba que es tan fácil de conseguir.

Si necesita tener un archivo real (es decir, para servir como parte de una prueba, procesar con una secuencia de comandos externa, etc.) puede usar algo similar al ejemplo de Mirko y crear un objeto de archivo después de asegurarse de que se almacenará en un lugar apropiado. - Aquí hay tres maneras de hacer eso:

  • Haga que su settings.MEDIA_ROOT de mkdtemp apunte a un directorio temporal (consulte la función mkdtemp del módulo tempfile Python). Esto funciona bien siempre que tenga algo como un STATIC_ROOT separado que use para los archivos de medios que forman parte de su código fuente.
  • Utilice un administrador de almacenamiento personalizado
  • Establezca la ruta del archivo manualmente en cada instancia del archivo o tenga una función personalizada upload_to para apuntar a algún lugar en el que su proceso de configuración / desmontaje de prueba purgue, como un subdirectorio de prueba, en MEDIA_ROOT .

Edición: la biblioteca de objetos simulados es nueva en Python versión 3.3. Para versiones anteriores de python, compruebe la versión de Michael Foord.


Normalmente pruebo campos de archivos en modelos usando doctest

>>> from django.core.files import File >>> s = SimpleModel() >>> s.audio_file = File(open("media/testfiles/testaudio.wav")) >>> s.save() >>> ... >>> s.delete()

Si necesito también probar archivos de carga con clientes de prueba.

En cuanto a los dispositivos, simplemente copio los archivos que necesito en una carpeta de prueba, después de modificar las rutas en el dispositivo.

p.ej

En un dispositivo que contiene modelos con archivos de archivo que apuntan a un directorio llamado "audio", reemplaza "audio": "audio / audio.wav" con "audio": "audio / test / audio.wav".
Ahora todo lo que tiene que hacer es copiar la carpeta de prueba, con los archivos necesarios, en "audio" en la configuración de prueba y luego eliminarla en tearDown.

No es la forma más limpia que pienso, pero eso es lo que hago.


Si solo desea crear un objeto que requiere FileField y no desea usar este campo , puede pasar cualquier ruta relativa (existente o no) como esta:

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

Entonces está listo para su uso.