Python 如何在django中使用captcha字段对表单进行单元测试?
我想通过使用表单对django视图进行单元测试。问题是这个表单有一个captcha字段(基于django simple 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 = {}
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
我所做的方式(在注意到您的答案之前)是解析未绑定的表单HTMLdom=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 }