Как выполнить модульное тестирование формы с полем капчи в django? - PullRequest
8 голосов
/ 01 июля 2010

Я хотел бы провести модульное тестирование представления django путем добавления формы.Проблема состоит в том, что эта форма имеет поле капчи (основано на 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)

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

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

Ответы [ 6 ]

16 голосов
/ 12 ноября 2013

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

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

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

if 'test' in sys.argv:
    CAPTCHA_TEST_MODE = True 
7 голосов
/ 02 июля 2010

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

from captcha.models import CaptchaStore

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

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

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

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

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

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

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

1 голос
/ 19 июня 2019

I проверено модулем это путем насмешки над ReCaptchaFieldСначала я добавил поле recaptcha в конструктор.Его нельзя добавить как обычное поле, потому что вы не сможете его смоделировать (после того, как код будет оценен до применения макета):

class MyForm(forms.ModelForm):

    ...

    def __init__(self, *args, **kwargs):
        # Add captcha in the constructor to allow mock it
        self.fields["captcha"] = ReCaptchaField()

Затем я просто заменил ReCaptchaField нане требуется CharField.Таким образом, я верю, что django-recaptcha будет работать.Я могу проверить только свои собственные вещи:

@mock.patch("trials.forms.ReCaptchaField", lambda: CharField(required=False))
def test_my_stuff(self):
    response = self.client.post(self.url, data_without_captcha)
    self.assert_my_response_fit_the_needs(response)
1 голос
/ 21 января 2016

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

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

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

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

1 голос
/ 01 июля 2010

Одним из решений является настройка «тестирование», которая имеет значение «истина» или «ложь».А потом просто

if not testing:
   # do captcha stuff here

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

0 голосов
/ 09 ноября 2010

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