2011-06-06 9 views
5

Estoy usando Django 1.2.3-3 + squeeze1 en Debian squeeze con PostgreSQL 8.4.7-0squeeze2 (aunque no creo que PostgreSQL sea relevante aquí), y estoy ejecutando pruebas de unidad Django basado en unittest con el siguiente montaje y desmontajeIDs de objeto django incrementan entre pruebas unitarias

def setUp(self): 
     print "running setup" 
     self.c = Client() 
     self.user = User.objects.create_user('faheem', '[email protected]', 'foo') 
     self.logged_in = self.c.login(username='faheem', password='foo') 
     settings.MEDIA_ROOT='/tmp/' 
     #settings.ZIP_UPLOAD='/var/tmp/zip/' 

    def tearDown(self): 
     print "running teardown" 
     FolderUpload.objects.all().delete() 
     FileUpload.objects.all().delete() 
     ZipFileUpload.objects.all().delete() 
     OldFileUpload.objects.all().delete() 
     # FIXME: Quick & dirty fix for the time being. Should make this a delete method. 
     os.system("rm -rf "+ settings.ZIP_UPLOAD + "/*") 

la idea es que todo lo que se elimina de la base de datos entre ejecutar pruebas unitarias. De acuerdo con la documentación de unittest, es para lo que tearDown es. El problema que estoy teniendo es que todavía parece haber algún estado guardado entre las diferentes pruebas unitarias. Específicamente, estoy viendo que los identificadores se incrementan. Lo que permite decir si creo uno ZipFileUpload objeto en test1, y luego crear un objeto en ZipFileUploadtest2, entonces yo esperaría que ambos sean identificadores de 1, pero lo que veo es que es Identificación del 1 para test1 y la identificación de 2test2. Esto tendría sentido si los identificadores provienen de algún índice que vive fuera de estas tablas. No sé lo suficiente acerca de cómo Diango hace esto para saber si ese es, de hecho, el caso. Si lo están haciendo de esta manera, no tengo idea de por qué. Cualquier aclaración sobre este punto sería apreciada.

De todos modos, me conformaría con una manera limpia de dejar la base de datos, si alguien puede sugerir una. Este método probablemente debería entrar en teadDown. Testing Django applications menciona la siguiente función, pero no pude importarla desde django.test.utils. Confusamente, esta función parece estar en django/db/backends/creation.py.

destroy_test_db (old_database_name, verbosidad = 1)

destruye la base de datos cuyo nombre está en almacenada en NOMBRE en las bases de datos, y establece el nombre de usar el nombre proporcionado.

La primera parte de esta frase está bien - "Destruir la base de datos cuyo nombre se almacena en NOMBRE en las bases de datos", pero lo que se entiende por "NOMBRE conjuntos de usar el nombre proporcionado" significa? Supongo que el nombre proporcionado es old_database_name,

No está claro qué NAME se encuentra en el contexto. ¿Es el NAME en DATABASES, y si es así, ¿por qué tengo que configurar algo que ya está configurado? Supongo que el nombre provisto es old_database_name, pero, de ser así, ¿por qué querría establecerlo en un argumento llamado old_database_name? Esta oración no se modifica en los documentos de desarrollo.

EDIT:

Después de una respuesta de Steve Mayne (véase más adelante), pensé que iba a elaborar en el fondo de esto un poco.

Esta aplicación fue escrita originalmente en 2007/2008/2009, incluidas las pruebas unitarias. Durante la mayor parte de ese tiempo, estaba usando versiones anteriores a 1.0 de Django. De acuerdo con Ken Cochran's Django Release History, 1.0 se lanzó el 3 de septiembre de 2008. La configuración descrita funcionó bien durante ese tiempo. Veo que la función anterior de tearDown fue escrita originalmente en diciembre de 2007. Entonces, ¿quizás cambió el comportamiento de Django?

En retrospectiva, me doy cuenta de que el vaciado de las tablas, como tearDown no más arriba, no garantiza que el recuento de Identificación se restablecerá a 1, ya que la secuencia puede ser un objeto separado de la mesa.

Gracias a Steve por su solución. Si existe, me gustaría escuchar acerca de una solución portátil para el restablecimiento de secuencia. También me interesaría una explicación de cómo hacer funcionar la función destroy_test_db.

+0

¿Por qué necesita que los ID enteros sean los mismos? Los identificadores se incrementan por la base de datos, no por Django per-se. –

+0

@Steve: no es crítico, pero las tablas se eliminan después de cada prueba, ¿no deberían los identificadores aumentar de uno nuevamente? En mi prueba, se usa para realizar un seguimiento de los objetos que se guardan y cuándo. –

+0

Sí, si abandona la base de datos, comenzará de nuevo. También puedes restablecer la secuencia de la tabla. Sin embargo, es peligroso confiar en las ID para brindarle información en las pruebas. El comportamiento de su aplicación debe ser independiente de ID. –

Respuesta

5

Puede restablecer la secuencia de ID en cada tabla usando el siguiente código SQL:

SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), 1); 

Sólo debe hacer esto si la tabla está vacía.

+0

Agradecemos su útil respuesta y comentarios. Mis pruebas no dependen de la verificación de id, no lo hace mi aplicación. Lo estoy haciendo solo para comprobar la cordura, y parece algo inofensivo en este contexto. Supongo que restablecer la secuencia de la tabla es una alternativa para eliminar la base de datos, y ciertamente más rápido. ¿Debo usar el enfoque descrito en [Ejecución de SQL personalizado directamente] (https://docs.djangoproject.com/en/1.2/topics/db/sql/#executing-custom-sql-directly) para hacer esto? –

+0

Sí, eso debería funcionar bien. Feliz de ayudar. –