代码之家  ›  专栏  ›  技术社区  ›  luc

如何在django中使用captcha字段对表单进行单元测试?

  •  8
  • luc  · 技术社区  · 15 年前

    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 回复  |  直到 15 年前
        1
  •  7
  •   Jim McGaw    15 年前

    我是这样处理的。导入实际包含验证码信息的模型:

    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)
    

    然后,我检索captcha实例数据并将其与表单一起发布。在我的例子中,POST期望“captcha\u 0”包含hashkey,“captcha\u 1”包含响应。

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

    如果在运行此测试之前从CaptchaStore实例开始,您可能需要对此进行一些调整。希望有帮助。

        2
  •  16
  •   Vinod Kurup    11 年前

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

    if 'test' in sys.argv:
        CAPTCHA_TEST_MODE = True 
    
        3
  •  3
  •   Michel Sabchuk    6 年前

    单元测试

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

    然后,我用一个不需要的CharField替换了ReCaptchaField。这样,我相信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)
    
        4
  •  1
  •   Wayne Werner    15 年前

    一种解决方案是设置“testing”为true或false。然后就

    if not testing:
       # do captcha stuff here
    

    它简单易用,而且容易切换。

        5
  •  1
  •   VStoykov    9 年前

    另一个解决方案类似于Jim McGaw的答案,但是不需要空表CaptchaStore表。

    captcha = CaptchaStore.objects.get(hashkey=CaptchaStore.generate_key())
    
    registration_data = { # other registration data here
                     'captcha_0': captcha.hashkey,
                     'captcha_1': captcha.response }
    

    这将为该测试生成新的验证码。

        6
  •  0
  •   luc    14 年前

    使用与Jim McGaw相似的方法,但使用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
    ...