[pyar] Django + Testing unitario

Hernan Lozano hernantz en gmail.com
Mie Dic 5 15:46:39 ART 2012


Hola Martin,
Entiendo la cuestión. Para probar ciertas funcionalidades en un test,
probablemente necesites otras funcionalidades, y  dependiendo de el caso *esas
otras funcionalidades tendrán sus tests unitarios correspondientes*.

*En este caso en particular* no veo porque seria un problema usar
directamente objetos del tipo Student y Practice, si no sobreescribiste sus
constructores, usarán los constructores de Model de Django (y supongo que
estarán testeados).  A mi parecer, siempre y cuando todas las partes de tu
código tengan sus tests correspondientes, no va a haber ninguna sorpresa...

De cualquier forma, mi respuesta es: no conozco una forma de mockear un
modelo Django en este momento. Así que sigo el tema de cerca y si veo algo
lo posteo acá.

PD: Podés leer este post [0] sobre como ir testeando modelos django, donde
para probar sus modelos, usan modelos reales.
PD2: Por ahí como dice Daniel, los mocks sirven más como ayuditas para no
testear cosas como un webservice o tocar todo el tiempo la base de datos,
etc, y no tanto para hacer más unitario un test...

[0] http://toastdriven.com/blog/2011/apr/17/guide-to-testing-in-django-2/







2012/12/5 Daniel Moisset <dmoisset en machinalis.com>

> No esta muy claro que uso querés hacer, pero normalmente lo que haces es
> hacer un Mock de las cosas que NO queres testear
>
> O sea, si queres hacer tests sobre Student y Practice, y ponele que llaman
> a un metodo de Teacher que no queres que se ejecute duranet el test, haces
> un mock de Teacher (o de su metodo), pero dejas Student y Practice tal cual.
>
> Otra cosa que no tiene que ver con tu pregunta:
>
> Tu código
>
> *       isinstance(self.student, Student)*
> *       isinstance(self.practice, Practice)*
>
> No hace nada (evalúa algo y tira el resultado, sin importar si fue
> verdadero o falso). Si lo que querés es que el test verifique que sean
> instancias, podés hacer:
>
> self.assertTrue(isinstance(self.studen, Student))
>
> Saludos,
>    Daniel
>
>
>
>
> 2012/12/5 Martin Zucchiatti Hotmail <tanomartin05 en hotmail.com>
>
>>   Hernan, te agradezco nuevamente tu tiempo y vuelvo a darle vida a mi
>> consulta....
>>
>> Si cambiamos el test por lo siguiente
>>  **
>> *class DeliveryTest(TestCase):*
>> *   def setUp(self):*
>> **
>> *      #self.student = MagicMock(spec=Student)*
>> ***       self.student = Student()*
>> ***       self.student.name = "Nombre y Apellido"*
>> **
>> **
>> *****       #self.practice = MagicMock(spec=Practice)*
>> *       self.practice = Practice()*
>> *       self.practice.uid = "Tp inicial"*
>> **
>> **
>> **
>> *   def testDeliveryToStringReturnNamePracticeNameStudentAndDeadLinePractice(self):
>> *
>> *       deliveryDate = "2012-11-25"*
>> *       str_practice_return = "Tp inicial - Nombre y Apellido -
>> 2012-11-25"*
>> *       delivery = Delivery()*
>> **
>> *       isinstance(self.student, Student)*
>> *       isinstance(self.practice, Practice)*
>> **
>> *       delivery.student = self.student*
>> *       delivery.practice = self.practice*
>> *       delivery.deliverDate = deliveryDate*
>> **
>> *       self.assertEqual(str(delivery), str_practice_return)*
>> **
>>
>> En el código cambiamos el MagicMock por el verdadero constructor de la
>> clase y el test anda perfecto.
>> Lo que quiero saber es si se puede suplir al constructor de la clase por
>> el Mock para solo utilizar funciones de la clase la cual estoy testeando.
>>  Desde ya muchas gracias por su ayuda
>>
>> Martin
>>
>>  *From:* Aníbal Lovaglio <aniballovaglio en yahoo.com.ar>
>> *Sent:* Wednesday, December 05, 2012 12:40 AM
>> *To:* Python Argentina <pyar en python.org.ar>
>> *Cc:* sercom2012 en googlegroups.com
>> *Subject:* Re: [pyar] Django + Testing unitario
>>
>>  Hola Hernán,
>> gracias por la respuesta, lo voy a probar ni bien pueda y comento a ver
>> como fue.
>> Saludos!
>>
>>   ------------------------------
>> *De:* Hernan Lozano <hernantz en gmail.com>
>> *Para:* Python Argentina <pyar en python.org.ar>
>> *Enviado:* martes, 4 de diciembre de 2012 8:58
>> *Asunto:* Re: [pyar] Django + Testing unitario
>>
>> Hola!
>> creo que error viene porque en el metodo __str__ de Delivery
>> estas llamando al __str__ de Student.
>> Como Delivery tiene un foreign key hacia un objeto Student, el ORM
>> va a tratar de buscar ese objeto en la base de datos.
>>
>> No se muy bien como funciona el MagicMock pero el objeto que estas
>> pasandole a tu Delivery() en el test no es un Student que herede de
>> django.models.Model,
>> y por ende no tiene el atributo _state.
>>
>> Mi sugerencia es probar sin un mock a ver que sale.
>>
>>
>> 2012/12/3 Aníbal Lovaglio <aniballovaglio en yahoo.com.ar>
>>
>>  Buenas a todos:
>>
>> Tengo una consulta para hacerles, hace un tiempo que estoy tratando de
>> hacer que funcione una cosa y no logre obtenerlo.
>> El problema es el siguiente.
>> Estoy tratando de testear unitariamente una clase la cual depende de
>> otras dos clases, para hacerlo mas facil voy a colocar la definicion de la
>> clase.
>>
>>  *class Delivery(models.Model):*
>> *    """Delivery class.*
>> *    *
>> *    It is the object or artifact that the Student presents as his work
>> for a*
>> *    given assignment. In this case it is considered required to be a
>> zip *
>> *    package.*
>> *     *
>> *    """*
>> *  *
>> *    file = models.FileField(upload_to=BASE_PATH + FOLDERNAME)*
>> *    student = models.ForeignKey(Student)*
>> *    practice = models.ForeignKey(Practice)*
>> *    deliverDate = models.DateField()*
>> *    *
>> *    def __str__(self):*
>> *        """Stringify the Delivery"""*
>> *        return (str(self.practice) + " - " + str(self.student) + " - "
>> + str(self.deliverDate))*
>>
>> Esta clase representa una entrega, la cual pertenece a un estudiante y es
>> esta hecha sobre una practica. (estas son las otras dos clases de la cual
>> depende.)
>>
>> Cuando quiero testear unitariamente esta clase por ejemplo su srt, para
>> hacer una prueba sencilla hago lo siguiente. Se que no sería algo
>> importante de testear pero necesito ver como funciona esto para poder
>> probar otras cosas mas complejas.
>>
>>  *class DeliveryTest(TestCase):*
>> *    def setUp(self):*
>> *        self.student = MagicMock(spec=Student)*
>> *        self.student.name = "Nombre y Apellido"*
>> *        self.practice = MagicMock(spec=Practice)*
>> *        self.practice.uid = "Tp inicial"*
>> *    *
>> *    def testDeliveryToStringReturnNamePracticeNameStudentAndDeadLinePractice(self):
>> *
>> *        deliveryDate = "2012-11-25"*
>> *        str_practice_return = "Tp inicial - Nombre y Apellido -
>> 2012-11-25"*
>> *        delivery = Delivery()*
>> *        *
>> *        isinstance(self.student, Student)*
>> *        isinstance(self.practice, Practice)*
>> *        *
>> *        delivery.student = self.student*
>> *        delivery.practice = self.practice*
>> *        delivery.deliverDate = deliveryDate*
>> *            *
>> *        self.assertEqual(str(delivery), str_practice_return)*
>>
>> Lo que estoy haciendo es tratando de crear un mock que reemplace a las
>> clases, lo hago para que sea realmente unitario el test y solo se pruebe la
>> clase que quiero probar sin depender de constructores de otras clases.
>>
>> Cuando corro el test, me tira el siguiente error...
>>
>>  *[localhost] local: python manage.py test model*
>> *Creating test database for alias 'default'...*
>> *E*
>> *======================================================================*
>> *ERROR: testDeliveryToStringReturnNamePracticeNameStudentAndDeadLinePractice
>> (seal.test.unit.deliveryTest.DeliveryTest)*
>> *----------------------------------------------------------------------*
>> *Traceback (most recent call last):*
>> *  File "/home/martin/workspace/seal/web/seal/test/unit/deliveryTest.py",
>> line 27, in testDeliveryToStringReturnNamePracticeNameStudentAndDeadLine
>> Practice*
>> *    delivery.student = self.student*
>> *  File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py",
>> line 369, in __set__*
>> *    instance._state.db = router.db_for_write(instance.__class__,
>> instance=value)*
>> *  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py",
>> line 141, in _route_db*
>> *    return hints['instance']._state.db or DEFAULT_DB_ALIAS*
>> *  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 658, in
>> __getattr__*
>> *    raise AttributeError("Mock object has no attribute %r" % name)*
>> *AttributeError: Mock object has no attribute '_state'*
>> *
>> *
>> *----------------------------------------------------------------------*
>> *Ran 1 test in 0.002s*
>> *
>> *
>> *FAILED (errors=1)*
>> *Destroying test database for alias 'default'...*
>> *
>> *
>> *Fatal error: local() encountered an error (return code 1) while
>> executing 'python manage.py test model'*
>> *
>> *
>> *Aborting.*
>>
>> Los isinstance pasan correctamente, pero cuando quiero asignar el mock a
>> la clase Delivery le tira el error antes mostardo.
>> Mi pregunta es: Se puede hacer lo que quiero hacer? Si es asi, alguien me
>> puede tirar un soga para resolverlo?
>>
>> Desde ya muchas gracias....
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>>  ------------------------------
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>>
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
>> Argentina - http://www.usla.org.ar
>>
>
>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20121205/a07d1f6c/attachment.html>


More information about the pyar mailing list