我想通过对表单进行单元测试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)
是否有任何方法对这些代码进行单元测试并在测试时摆脱验证码?
提前致谢
答案 0 :(得分:16)
我知道这是一个旧帖子,但是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设置只应在测试期间使用。我的settings.py:
if 'test' in sys.argv:
CAPTCHA_TEST_MODE = True
答案 1 :(得分:7)
这是我绕过它的方式。导入实际包含验证码信息的模型:
from captcha.models import CaptchaStore
首先,我检查测试验证码表是否为空:
captcha_count = CaptchaStore.objects.count()
self.failUnlessEqual(captcha_count, 0)
加载页面后(在这种情况下,它是一个注册页面),检查是否有新的验证码对象实例:
captcha_count = CaptchaStore.objects.count()
self.failUnlessEqual(captcha_count, 1)
然后,我检索验证码实例数据并使用表单POST。在我的例子中,POST期望'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实例,则可能需要稍微调整一下。希望有所帮助。
答案 2 :(得分:1)
一种解决方案是设置“测试”,无论是真还是假。然后只是
if not testing:
# do captcha stuff here
简单易用,易于切换。
答案 3 :(得分:1)
另一种解决方案类似于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 }
这将为该测试生成新的验证码。
答案 4 :(得分:1)
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)
答案 5 :(得分:0)
采用与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
...
答案 6 :(得分:0)
这是我们如何做到的。
@patch("captcha.fields.ReCaptchaField.validate")
def test_contact_view(self, validate_method):
response = self.client.get(reverse("contact"))
self.assertEqual(response.status_code, 200)
data = {
"name": "Bob Johnson",
"email": "big_johnson@home.com",
"phone": "800-212-2001",
"subject": "I want Axis!",
"message": "This is a giant\nThree liner..\nLove ya\n",
"captcha": "XXX",
}
validate_method.return_value = True
response = self.client.post(reverse("contact"), data=data)
self.assertEqual(response.status_code, 302)