2009-12-15 2 views
6

Me interesa aprender a realizar pruebas de Doctest y de unidad de una manera más ágil/BDD. He encontrado algunos tutoriales que parecen razonables, pero solo son miniaturas. Lo que realmente me gustaría ver es el código fuente de algunos proyectos de Django que se desarrollaron al estilo BDD.Ejemplos del uso de Doctest en Django de forma Agile/BDD

Lo que no entiendo es cómo maneja los objetos solicitados, etc. Tengo una situación en la que implementé mi aplicación y obtengo un comportamiento completamente diferente en la producción que hice en desarrollo o incluso desde el Shell de Python en el servidor de producción. Espero que algunos Doctests me ayuden a diagnosticar esto y que me abran la puerta a un proceso más ágil para escribir las pruebas primero.

Específicamente, aquí está el código que estoy tratando de prueba:

def match_pictures_with_products(queryset, number_of_images = 3):  
    products = [] 
    i = 0  
    for product in queryset: 
     if i < (number_of_images): 
      image = product.imagemain_set.all()[:1] 
      product.photo_url = image[0].photo.url 

     products.append(product) 
     i += 1 

    return products 

def index(request): 
    """returns the top 10 most clicked products"""  
    products = Product.objects.all()[:10] 
    products = match_pictures_with_products(products, 10) . 
    return render_to_response('products/product_list.html', {'products': products}) 

¿Cómo se crea un doctest que asegura que el índice vuelve 10 objetos?
Las consultas sobre productos parecen funcionar bien desde el shell en el servidor de producción. El servidor real no devuelve ningún producto.

+0

Si quieres una herramienta BDD, prueba la lechuga. –

Respuesta

3

Me he hecho la misma pregunta antes. He encontrado prueba unitaria para ser de utilidad limitada para cosas como las vistas, los métodos y los gestores modelo porque

  1. Tienes que ser capaz de montaje y desmontaje de un conjunto de datos de prueba a utilizar realmente para las pruebas
  2. Vistas necesitan tomar un objeto de solicitud. En un doctest, ¿de dónde viene eso?

Por esa razón, siempre he usado el marco Django unit testing que maneja todo esto para usted. Desafortunadamente, sin embargo, no obtienes algunos de los beneficios de los doctests y hace que TDD/BDD sea más difícil de hacer. Lo siguiente es pura especulación acerca de cómo puede hacer que esto funcione:

Creo que querría tomar doctests de sus respectivos módulos y funciones y ejecutarlos dentro del marco de prueba de la unidad. Esto se encargaría de la configuración/eliminación de datos de prueba. Si tus doctests se ejecutaron desde un método de prueba de algo que subclasifica la prueba unittest.TestCase de Django, podrían usar ese DB de prueba. También podría pasar un objeto de solicitud simulada al contexto de ejecución de la prueba de doc. Aquí hay un Django snippet que proporciona un objeto de solicitud simulada y info en él. Supongamos que quiere probar las cadenas de documentos desde todas las vistas de una aplicación. Podrías hacer algo como esto en las pruebas.PY:

from ??? import RequestFactory 
from doctest import testmod, DocTestFailure 
from django.test import TestCase 

from myapp import views 

class MyAppTest(TestCase): 

    fixtures = ['test_data.json'] 

    def test_doctests(self):     
     try: 
      testmod(views, extraglobs={ 
       'REQUEST': RequestFactory() 
      }, raise_on_error=True) 
     except DocTestFailure, e: 
      self.fail(e) 

Este debe permitirá hacer algo como esto:

def index(request): 
    """ 
    returns the top 10 most clicked products 

    >>> response = index(REQUEST) 
    >>> [test response content here] 

    """  
    products = Product.objects.all()[:10] 
    products = match_pictures_with_products(products, 10) . 
    return render_to_response('products/product_list.html', {'products': products}) 

Una vez más, esto es sólo la parte superior de la cabeza y no del todo probado, pero es la única manera de que creo que podrías hacer lo que quieras sin solo poner todas tus pruebas de vista en el marco de prueba de la unidad.

0

El paquete zope.testbrowser puede ser útil en sus doctests, ya que desea analizar la respuesta HTML representada de su servidor de producción.

1

La forma en que está escrita su vista, sería difícil de probar. Tendría que raspar el html para ver si el contenido que desea está presente, y luego está probando más de lo que necesita. Sería mejor reescribir su vista para que sea más fácil de probar. Comience con la parametrización de su nombre de la plantilla, por lo que puede crear una plantilla de prueba sencilla:

def index(request, template_name='products/product_list.html'): 
    """returns the top 10 most clicked products"""  
    products = Product.objects.all()[:10] 
    products = match_pictures_with_products(products, 10) . 
    return render_to_response(template_name, {'products': products}) 

entonces usted puede escribir una plantilla simple que simplemente cuenta el número de productos:

{{ products.count }} 

Y asegúrese de que la plantilla devuelve "10".

+0

No estoy seguro de estar siguiendo esto. ¿Probarías la plantilla con un Doctest? Me encantaría ver algunos proyectos de Django donde esto se ha implementado. – BryanWheelock

1

Puede utilizar el django testclient y probar las variables de contexto que consiga el sistema:

>>> response = client.get('/foo/') 
>>> response.context['name'] 
'Arthur' 

También puede comprobar el código de respuesta para asegurarse de que la página volvió un éxito 200.