【发布时间】:2023-04-02 10:41:01
【问题描述】:
我想要一些关于如何测试我的一个 Django 表单中的错误的帮助或建议。它负责确保用户输入有效的会话 ID,该 ID 用作 3rd 方 API 的身份验证令牌。有效 ID 长度为 32 个字符,由字母数字组成。
我选择了一种验证字段的方法,而不是模型。
当我使用开发服务器手动测试它时,它按预期工作。 IE。如果用户粘贴长度错误的字符串或带有特殊字符的字符串,则该字段的 validate 方法会创建错误,然后通过 for 循环在 html 模板中的表单错误周围显示。
我不明白以下错误。我临时修改了 testcases.py 以证明错误正在传递给它 - 那么为什么 context[form].errors 是一个“属性”以及它是如何到达那里的?
我正在使用 Django 1.10 和 Python 3.5.1
======================================================================
ERROR: test_index_sessid_short_strings (poe.tests.TestBannerButtons)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/adam.green/Documents/workspace/poe-client/poetools_project/poe/tests.py", line 105, in test_index_sessid_short_strings
self.assertFormError(response, 'form', "new_sessid" , 'The Session ID needs to be exactly 32 characters long')
File "/Users/adam.green/.virtualenvs/poe-tools/lib/python3.5/site-packages/django/test/testcases.py", line 421, in assertFormError
if field in context[form].errors:
TypeError: argument of type 'property' is not iterable
----------------------------------------------------------------------
Ran 1 test in 0.805s
测试
def test_index_sessid_short_strings(self):
url = reverse('index')
response = self.client.post(url, {'new_sessid': "f14"})
self.assertFormError(response, 'form', "new_sessid" , 'The Session ID needs to be exactly 32 characters long')
form.py
class SessID(forms.Field):
def validate(self, session_id):
"""Check if value consists only of valid emails."""
# Use the parent's handling of required fields, etc.
super().validate(session_id)
if len(session_id) < 32 > len(session_id):
raise ValidationError(
_('The Session ID needs to be exactly 32 characters long'),
code = 'sessid wrong length'
)
if not re.match("^[A-Za-z0-9]*$", session_id):
raise ValidationError(
_('The Session ID should only have letters and numbers, no special characters'),
code = 'sessid not alphanumeric'
)
class ResetSessID(forms.ModelForm):
new_sessid = SessID()
#forms.CharField(widget=forms.TextInput(attrs={'class':'special', 'size': '32'}) )
def __init__(self, *args, **kwargs):
super(ResetSessID, self).__init__(*args, **kwargs)
stdlogger.info("init of ResetSessID")
#print("dir")#, self.fields.items['new_sessid'])
if kwargs.get('instance'):
new_sessid = kwargs['instance'].new_essid
stdlogger.info("inner kwargs loop")
return super(ResetSessID, self).__init__(*args, **kwargs)
class Meta:
model = PoeAccount
exclude = ("acc_name", "sessid")
def clean(self):
if 'reg_button' in self.data:
print("amazing")
views.py
def index(request):
request.session.set_test_cookie()
item_category_list = ItemCategory.objects.all()
modifications_list = FixCategory.objects.all()
context_dict = {}
if request.user.is_authenticated:
if request.method == 'POST':
form = ResetSessID(request.POST)
if form.is_valid():
# get the right account
me = poe.models.PoeAccount.objects.get(
acc_name = request.user.poeuser.poe_account_name
)
# commit new sessid passed to here
# me.full_clean()
me.sessid = form['new_sessid'].value()
me.save(update_fields=['sessid'])
context_dict["old_sessid"] = me.sessid
context_dict['form'] = ResetSessID
response = render(request,'poe/index.html', context_dict)
#return response
else:
context_dict['errors'] = form.errors
print("form has errors", form.errors)
me = poe.models.PoeAccount.objects.get(
acc_name = request.user.poeuser.poe_account_name
)
context_dict['errors'] = form.errors
context_dict["old_sessid"] = me.sessid
context_dict['form'] = ResetSessID
for x, y in form.errors.items():
print("errors", x, y)
response = render(request,'poe/index.html', context_dict)
#return response
else:
context_dict = {'form': ResetSessID}
me = poe.models.PoeAccount.objects.get(acc_name = request.user.poeuser.poe_account_name)
context_dict["old_sessid"] = me.sessid
context_dict.update({'item_categories': item_category_list, 'mods': modifications_list})
# make sure the session keeps track of the number of visits
visits = request.session.get('visits')
if not visits:
visits = 1
reset_last_visit_time = False
last_visit = request.session.get('last_visit')
if last_visit:
last_visit_time = datetime.datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S")
if (datetime.datetime.now() - last_visit_time).seconds > 0:
# ...reassign the value of the cookie to +1 of what it was before...
visits = visits + 1
# ...and update the last visit cookie, too.
reset_last_visit_time = True
else:
# Cookie last_visit doesn't exist, so create it to the current date/time.
reset_last_visit_time = True
# make sure the session keeps track of time last visited
if reset_last_visit_time:
request.session['last_visit'] = str(datetime.datetime.now())
request.session['visits'] = visits
context_dict['visits'] = visits
#print("context_dict", context_dict)
response = render(request,'poe/index.html', context_dict)
return response
【问题讨论】:
标签: django python-3.x unit-testing