Как модульный тест формы с полем captcha в django?

Я хочу модульного тестирования видом Джанго по sumitting форму. Проблема в том, что эта форма имеет поле captcha (на основе django-simple-captcha).

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()

тестовый код:

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)

есть ли какой-либо подход к модульному тестированию этого кода и избавлению от капчи при тестировании?

спасибо заранее

5 ответов


вот как я обошел это. Импортируйте модель, которая фактически содержит информацию Captcha:

from captcha.models import CaptchaStore

во-первых, я проверяю, что тестовая таблица captcha пуста:

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

после загрузки страницы (в данном случае это страница регистрации) проверьте, что есть новый экземпляр объекта captcha:

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

затем я извлекаю данные экземпляра captcha и отправляю их с формой. В моем случае, пост ожидает 'captcha_0', чтобы содержать hashkey, и captcha_1 в содержать ответ.

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

возможно, вам придется немного изменить это, если вы начнете с экземпляров CaptchaStore перед запуском этого теста. Надеюсь, это поможет.


Я знаю, что это старый пост, но django-simple-captcha теперь имеет параметр CAPTCHA_TEST_MODE, который делает captcha успешным, если вы предоставите значение "передано". Вам просто нужно обязательно отправить что-то для обоих полей ввода captcha:

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

параметр CAPTCHA_TEST_MODE следует использовать только во время тестов. Мой settings.py:

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

одно решение имеет настройку "тестирование", которая является либо истинной, либо ложной. А потом просто

if not testing:
   # do captcha stuff here

Это просто и легко, и легко переключаться.


другие решения, которые похожи на ответ Джима Макгоу, но устраняют необходимость пустой таблицы CaptchaStore.

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

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

Это создаст новую капчу только для этого теста.


с аналогичным подходом, чем Джим Макгоу, но с использованием 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
...