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

Python 如何在django中使用captcha字段对表单进行单元测试?,python,django,unit-testing,captcha,Python,Django,Unit Testing,Captcha,我想通过使用表单对django视图进行单元测试。问题是这个表单有一个captcha字段(基于django simple captcha) 测试代码: class ContactFormTest(TestCase): def test_submitform(self): """Test that the contact page""" url = reverse('contact_form') form_data = {}

我想通过使用表单对django视图进行单元测试。问题是这个表单有一个captcha字段(基于django simple captcha)

测试代码:

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)
有什么方法可以对代码进行单元测试,并在测试时去掉验证码


提前感谢

一个解决方案是设置“测试”为真或假。然后就

if not testing:
   # do captcha stuff here

它简单易用,切换也很容易。

以下是我的解决方法。导入实际包含验证码信息的模型:

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实例数据并将其与表单一起发布。在我的例子中,帖子希望“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实例开始,您可能需要对此进行一些调整。希望能有所帮助。

采用与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
...

我知道这是一篇老文章,但django simple captcha现在有一个设置captcha_TEST_模式,如果您提供“PASSED”值,它将使captcha成功。您只需确保为两个验证码输入字段发送内容:

post_data['captcha_0'] = 'dummy-value'
post_data['captcha_1'] = 'PASSED'
self.client.post(url, data=post_data)
验证码测试模式设置只能在测试期间使用。My settings.py:

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

另一个解决方案类似于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 }
这将仅为该测试生成新的验证码。

我通过模拟ReCaptchaField对其进行了单元测试。首先,我在构造函数中添加了recaptcha字段。无法将其添加为常规字段,因为您将无法对其进行模拟(一旦在应用模拟之前对代码进行了评估):

类MyForm(forms.ModelForm):
...
定义初始化(self,*args,**kwargs):
#在构造函数中添加captcha以允许对其进行模拟
self.fields[“captcha”]=ReCaptchaField()
然后,我用一个不需要的CharField替换了ReCaptchaField。这样,我相信django recaptcha会奏效。我只能测试我自己的东西:

@mock.patch(“trials.forms.ReCaptchaField”,lambda:CharField(必需=False))
def测试我的东西(自我):
response=self.client.post(self.url,没有验证码的数据)
self.assert\u my\u response\u fit\u所需(响应)

它可以工作,但在将表单导入测试模块之前,必须设置settings.UNIT\u TEST=True。这就是我犯错误的原因。您也可以在设置文件中设置测试:
如果sys.argv:testing=True
我所做的方式(在注意到您的答案之前)是解析未绑定的表单HTML
dom=PyQuery('{})。format(f.as_p())
,从那里获取哈希值
hashkey=dom('input[name=“captcha_0”]'))。attr('value'))
然后使用它查询数据库。其余的基本相同。希望有人会这样做。如果其他人也像我一样来到这里,我无意中发现了这篇文章,试图为
django recaptcha
包找到类似的答案;结果他们也有一个设置。他们的文档描述了它的用途:适用于使用django recaptcha的人,需要在你的unittest中做一篇文章,你还需要像这样发送“g-recaptcha-response”:self.client.post(url,{“g-recaptcha-response”:“PASSED”})现在也可以使用
@override\u设置(CAPTCHA\u TEST\u MODE=True)
来自django.test import override_settings;但不幸的是,截至2019年2月,此设置仅在应用程序启动时读取一次。请参阅,为了避免像我这样健忘的人需要查找它们,您需要:
来自django.db.models import CharField
来自单元测试导入模拟
captcha = CaptchaStore.objects.get(hashkey=CaptchaStore.generate_key())

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