2010-05-15 873 views
18

Tengo el siguiente caso de prueba Django que me está dando errores:problemas utilizando el modelo del usuario en la unidad de Django pone a prueba

class MyTesting(unittest.TestCase): 
    def setUp(self): 
     self.u1 = User.objects.create(username='user1') 
     self.up1 = UserProfile.objects.create(user=self.u1) 

    def testA(self): 
     ... 

    def testB(self): 
     ... 

Cuando ejecuto mis pruebas, testA pasaré con éxito pero antes de testB aperturas, me sale el siguiente de error:

IntegrityError: column username is not unique 

es claro que se está tratando de crear self.u1 antes de cada caso de prueba y encontrar que ya existe en la base de datos. ¿Cómo hago para que se limpie adecuadamente después de cada caso de prueba para que los casos posteriores se ejecuten correctamente?

Respuesta

27

setUp y tearDown Los métodos en Unittest se llaman antes y después de cada caso de prueba. Defina el método tearDown que elimina el usuario creado.

class MyTesting(unittest.TestCase): 
    def setUp(self): 
     self.u1 = User.objects.create(username='user1') 
     self.up1 = UserProfile.objects.create(user=self.u1) 

    def testA(self): 
     ... 

    def tearDown(self): 
     self.up1.delete() 
     self.u1.delete() 

También aconsejaría a create user profiles usando post_save señal a menos que realmente desea crear el perfil de usuario manualmente para cada usuario.

Seguimiento en Eliminar comentario:

De Django docs:

When Django deletes an object, it emulates the behavior of the SQL constraint ON DELETE CASCADE -- in other words, any objects which had foreign keys pointing at the object to be deleted will be deleted along with it.

En su caso, el perfil de usuario está apuntando a usuario por lo que debe eliminar el usuario primero para eliminar el perfil en el Mismo tiempo.

+0

Gracias! El problema que estoy teniendo ahora es que cuando elimino up1, la eliminación no se inicia en cascada y elimina u1 también, aunque he especificado User como una clave foránea de UserProfile. p.ej. 'user = models.ForeignKey (User, unique = True)' – theycallmemorty

+0

En realidad, debe eliminar al usuario para poder poner en cascada y eliminar el perfil de usuario de una vez, o puede eliminar primero el perfil de usuario y luego el usuario. –

+0

Bah ... Leí eso no en los documentos, pero por alguna razón me confundí acerca de qué dirección apuntaba la clave externa ... – theycallmemorty

2

Precisamente, setUp existe para el propósito de ejecutar una vez antes de cada caso de prueba.

El método inverso, el que se ejecuta una vez después cada caso de prueba, se llama tearDown: ahí es donde se elimina self.u1 etc (presumiblemente con sólo llamar self.u1.delete(), a menos que tenga requisitos de limpieza especializados complementaria a solo borrando el objeto).

8

Si desea que django limpie automáticamente la base de datos de prueba después de ejecutar cada prueba, debe ampliar django.test.TestCase, NO django.utils.unittest.TestCase (como lo hace actualmente).

Es una buena práctica volcar la base de datos después de cada prueba para que pueda estar seguro de que las pruebas son consistentes, pero tenga en cuenta que las pruebas se ejecutarán más lentamente con esta sobrecarga adicional.

Consulte la sección ADVERTENCIA ADVERTENCIA en el "Writing Tests" Django Docs.

Cuestiones relacionadas