Hou*_*man 63 django unit-testing
我在理解如何为django设计单元测试时遇到问题.
根据我的理解,一次性测试整个视图似乎是不可能的.我们需要区分请求的前后状态.但我不知道如何设计这个.有没有现实生活中的例子?
查看文档,示例过于简化,仅关注模型.
@login_required
def call_view(request, contact_id):
profile = request.user.get_profile()
if request.POST:
form = CallsForm(profile.company, request.POST)
if form.is_valid()
return HttpResponseRedirect('/contact/' + contact_id + '/calls/')
else:
form = CallsForm(profile.company, instance=call)
variables = RequestContext(request, {'form':form}
return render_to_response('conversation.html', variables)
Run Code Online (Sandbox Code Playgroud)
更新:
试图成功测试工作,但它仍然失败:
def test_contact_view_success(self):
# same again, but with valid data, then
self.client.login(username='username1', password='password1')
response = self.client.post('/contact/add/', {u'last_name': [u'Johnson'], })
self.assertRedirects(response, '/')
Run Code Online (Sandbox Code Playgroud)
错误信息:
AssertionError: Response didn't redirect as expected: Response code was 200 (expected 302)
Run Code Online (Sandbox Code Playgroud)
我认为这是因为form.is_valid()失败并且它没有重定向,对吗?
sup*_*cuo 103
NB NB! 我在下面描述的并不是严格意义上的"单元测试"; 为Django视图代码编写独立的单元测试几乎是不可能的.这更像是一次集成测试......
你的观点有几条路径是对的:
GET或POST匿名用户(应重定向到登录页面)GET或者POST没有配置文件的登录用户(应该引发UserProfile.DoesNotExist异常)GET 登录用户(应显示表单)POST 登录用户使用空白数据(应显示表单错误)POST 由具有无效数据的登录用户(应显示表单错误)POST 由具有有效数据的登录用户(应重定向)测试1实际上只是测试@login_required,所以你可以跳过它.无论如何我倾向于测试它(以防我或其他人忘记使用该装饰器).
我不知道在故障情况下(500错误页面)2是你真正想要的.我会找出你想要发生的事情(也许使用get_or_create(),或捕获DoesNotExist异常并以这种方式创建一个新的配置文件).
根据您拥有的自定义验证量,可能不需要进行4次测试.
无论如何,考虑到上述所有情况,我会做类似的事情:
from django.test import TestCase
class TestCalls(TestCase):
def test_call_view_denies_anonymous(self):
response = self.client.get('/url/to/view', follow=True)
self.assertRedirects(response, '/login/')
response = self.client.post('/url/to/view', follow=True)
self.assertRedirects(response, '/login/')
def test_call_view_loads(self):
self.client.login(username='user', password='test') # defined in fixture or with factory in setUp()
response = self.client.get('/url/to/view')
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'conversation.html')
def test_call_view_fails_blank(self):
self.client.login(username='user', password='test')
response = self.client.post('/url/to/view', {}) # blank data dictionary
self.assertFormError(response, 'form', 'some_field', 'This field is required.')
# etc. ...
def test_call_view_fails_invalid(self):
# as above, but with invalid rather than blank data in dictionary
def test_call_view_fails_invalid(self):
# same again, but with valid data, then
self.assertRedirects(response, '/contact/1/calls/')
Run Code Online (Sandbox Code Playgroud)
显然,这里的缺点是硬编码的URL.您可以在测试中使用reverse()或使用构建请求RequestFactory并将视图作为方法(而不是URL)调用.但是,使用后一种方法,您仍然需要使用硬编码值或reverse()测试重定向目标.
希望这可以帮助.