2010-11-18 13 views
30

Tengo un modelo llamado Thing con un atributo llamado name, y quiero que el nombre sea un campo char que es solo 3 caracteres de largo.cómo escribir la prueba de django para fallar?

¿Cómo escribo una prueba para eso?

class TestCase1(TestCase): 
    def test1(self): 
     thing = Thing(name='1234') 

que la prueba debería fallar. ¿Cómo escribo correctamente la prueba para que la prueba pase cuando ese objeto falla?

Respuesta

58

Si espera que Thing (name = '1234') haga una excepción, hay dos formas de solucionar esto.

Uno es utilizar assertRaises de Django (en realidad de unittest/unittest2):

def mytest(self): 
    self.assertRaises(FooException, Thing, name='1234') 

Esta falla a menos Cosa (name = '1234') genera un error FooException. Otra forma consiste en detectar la excepción esperada y levantar uno si esto no sucede, como esto:

def mytest(self): 
    try: 
     thing = Thing(name='1234') 
     self.fail("your message here") 
    except FooException: 
     pass 

Obviamente, sustituya el FooException con el que espera obtener de la creación del objeto con demasiado tiempo una cadena. ¿Error de validacion?

Una tercera opción (a partir de Python 2.7) es el uso de assertRaises como un gestor de contexto, lo que hace más limpia, más legible el código:

def mytest(self): 
    with self.assertRaises(FooException): 
     thing = Thing(name='1234') 

Lamentablemente, esto no permite mensajes de error de prueba especiales , documenta bien tus pruebas. Ver https://hg.python.org/cpython/file/2.7/Lib/unittest/case.py#l97 para más detalles.

+0

Uso assertRaises con bastante frecuencia. –

+0

Lo hago también, pero la sintaxis toma un tiempo para acostumbrarse. – GDorn

+1

en Python versión 2.6.5, la firma de la función es diferente. Copiado del código python: 'def failUnlessRaises (self, excClass, callableObj, * args, ** kwargs)' y luego 'callableObj (* args, ** kwargs)'. Entonces, en el ejemplo de esta publicación, sería 'self.assertRaises (FooException, Thing, name = '1234')'. No estoy seguro de por qué la firma de mi función es diferente, pero eso es lo que funciona. –

0

Algo como esto debería funcionar:

thing = Thing.objects.create(name='1234') 
# not sure if you need here .get() or if. create() truncates the field on its own 
self.assertEqual(thing.name, '123') # or: self.assertEqual(len(thing.name), 3) 

- pero dicha prueba se ve raro :-)

Además, cabe destacar que backend MySQLdb elevará excepción de advertencia para notificarle de truncar la cadena, por lo Es posible que desee comprobarlo con assertRaises.

0

Actualmente estoy usando el decorador expectedFailure de unittest. Eso funciona como se anuncia: falla cuando no hay ningún error, pasa cuando hay una falla.

Utilizo expectedFailure para verificar que mis rutinas-afirmadas personalizadas realmente funcionen y no solo aprueben todo OK.

import unittest 
from django.test import TestCase 

class EmojiTestCase(TestCase): 

    @unittest.expectedFailure 
    def testCustomAssert(self): 
     self.assertHappyFace(':(') # must fail. 

Pero imprime un mensaje de advertencia durante la prueba. Lo uso con Django y Nariz. ¿Qué others han visto, también.

/usr/lib64/python3.4/unittest/case.py:525: RuntimeWarning: TestResult no tiene un método addExpectedFailure, informando a medida que pasa RuntimeWarning)

Vine aquí para encontrar una mejor solución, pero no encontró ninguna. Así que al menos quería decirle a los demás que eso es con lo que he estado trabajando.

Cuestiones relacionadas