2010-07-01 17 views
7

Me gustaría probar la unidad de una vista django mediante la sumisión de un formulario. El problema es que esta forma tiene un campo de captcha (basado en django-simple-captcha).¿Cómo probar un formulario con un campo captcha en django?

from django import forms 
from captcha.fields import CaptchaField 

class ContactForm(forms.forms.Form): 
    """ 
    The information needed for being able to download 
    """ 
    lastname = forms.CharField(max_length=30, label='Last name') 
    firstname = forms.CharField(max_length=30, label='First name') 
    ... 
    captcha = CaptchaField() 

El código de prueba:

class ContactFormTest(TestCase): 

    def test_submitform(self): 
     """Test that the contact page""" 
     url = reverse('contact_form') 

     form_data = {} 
     form_data['firstname'] = 'Paul' 
     form_data['lastname'] = 'Macca' 
     form_data['captcha'] = '28if' 

     response = self.client.post(url, form_data, follow=True) 

¿Hay alguna aproximación a la unidad de prueba de este código y deshacerse del código de imagen cuando se prueba?

Gracias de antemano

+0

En caso de que otros terminen aquí como lo hice, tropecé con esta publicación tratando de encontrar una respuesta similar para el paquete 'django-recaptcha'; resulta que también tienen un ajuste. Sus documentos describen su uso: https://github.com/praekelt/django-recaptcha –

Respuesta

6

Así fue como lo supere. Importar el modelo que lleva a cabo realmente Captcha Info:

from captcha.models import CaptchaStore 

En primer lugar, puedo comprobar que la tabla de prueba código de imagen está vacía:

captcha_count = CaptchaStore.objects.count() 
self.failUnlessEqual(captcha_count, 0) 

Después de cargar la página (en este caso, se trata de una página de registro), comprobar que hay una nueva instancia del objeto de la imagen:

captcha_count = CaptchaStore.objects.count() 
self.failUnlessEqual(captcha_count, 1) 

Entonces, puedo recuperar los datos de instancia código de imagen y POST que con la forma. En mi caso, el POST espera que 'captcha_0' contenga el hashkey y 'captcha_1' para contener la respuesta.

captcha = CaptchaStore.objects.all()[0] 
registration_data = { # other registration data here 
        'captcha_0': captcha.hashkey, 
        'captcha_1': captcha.response } 

Es posible que tenga que modificar esto un poco si comienza con las instancias de CaptchaStore antes de ejecutar esta prueba. Espero que ayude.

+0

De la forma en que lo hice (antes de notar tu respuesta) fue analizar el formato HTML libre 'dom = PyQuery (' {}' .format (f.as_p())', obtiene el hash de allí 'hashkey = dom ('input [name =" captcha_0 "]'). attr ('value ') 'y luego consultar la base de datos que lo usa. El resto es más o menos el mismo. Espero que alguien lo espere. – alfetopito

1

Una solución es tener una "prueba" entorno que es verdadero o falso. Y luego solo

if not testing: 
    # do captcha stuff here 

Es simple y fácil, y es fácil de alternar.

+0

Funciona, pero las configuraciones.UNIT_TEST = True se debe establecer antes de importar el formulario en el módulo de prueba.Esa fue la causa de mi error – luc

+1

, también puedes establecer las pruebas en el archivo de configuración: 'if" test "en sys.argv: TESTING = True' – leech

0

Con un enfoque similar que Jim McGaw pero utilizando BeautifulSoup:

from captcha.models import CaptchaStore 
from BeautifulSoup import BeautifulSoup 

data = {...} #The data to post 
soup = BeautifulSoup(self.client.get(url).content) 
for field_name in ('captcha_0', ...): #get fields from the form 
    data[field_name] = soup.find('input',{'name':field_name})['value'] 
captcha = CaptchaStore.objects.get(hashkey=data['captcha_0']) 
data['captcha_1'] = captcha.challenge 
response = self.client.post(url, data=data) 

# check the results 
... 
10

Sé que esto es una entrada antigua, pero Django-simple código de imagen tiene ahora un CAPTCHA_TEST_MODE entorno que hace que el código de imagen éxito si usted proporciona el valor 'PASADO'. Usted sólo tiene que asegurarse de enviar algo para los dos campos de entrada de la imagen:

post_data['captcha_0'] = 'dummy-value' 
post_data['captcha_1'] = 'PASSED' 
self.client.post(url, data=post_data) 

El ajuste CAPTCHA_TEST_MODE deberían utilizarse sólo durante las pruebas. Mi settings.py:

if 'test' in sys.argv: 
    CAPTCHA_TEST_MODE = True 
1

Otras soluciones que es similar a la respuesta de Jim McGaw, pero elimina la necesidad de mesa CaptchaStore vacía.

captcha = CaptchaStore.objects.get(hashkey=CaptchaStore.generate_key()) 

registration_data = { # other registration data here 
       'captcha_0': captcha.hashkey, 
       'captcha_1': captcha.response } 

Esto generará un nuevo captcha solo para esa prueba.

Cuestiones relacionadas