如何编写django视图的unit testing?

我有问题了解unit testing应该如何为djangodevise。

从我的理解来看,一次性testing整个视图似乎是不可能的。 我们需要区分请求的前后状态。 但我不知道如何devise这个。 有没有真实的生活的例子?

看看这些文档,这些例子太简单了,只关注模型。

@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) 

更新:

试图做出成功的testing工作,但仍然失败:

 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, '/') 

错误信息:

 AssertionError: Response didn't redirect as expected: Response code was 200 (expected 302) 

我认为这是因为form.is_valid()失败,它不redirect,正确?

注意! 我在下面描述的不是严格的“unit testing”。 为Django视图代码编写独立的unit testing几乎是不可能的。 这是更多的集成testing…

你说得对,有几种途径可以通过你的观点:

  1. 由匿名用户进行GETPOST (应redirect到login页面)
  2. 通过没有configuration文件的login用户进行GETPOST (应引发UserProfile.DoesNotExistexception)
  3. 通过login用户GET (应显示表单)
  4. login用户使用空白数据POST (应显示表单错误)
  5. login用户使用无效数据POST (应显示表单错误)
  6. 通过login的用户使用有效数据进行POST (应该redirect)

testing1.实际上只是testing@login_required ,所以你可以跳过它。 无论如何,我倾向于testing它(以防万一我或其他人忘记使用这个装饰器)。

我不确定2中的失败情况(500错误页面)是你真正想要的。 我会找出你想要发生什么(也许使用get_or_create() ,或者捕获DoesNotExistexception,并以这种方式创build一个新的configuration文件)。

根据你有多less自定义validation,4.可能不需要testing。

无论如何,鉴于以上所有,我会做一些事情:

 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/') 

显然,这里的一个缺点是硬编码的URL。 您可以在testing中使用reverse()或使用RequestFactory构build请求,并将您的视图作为方法(而不是URL)调用。 但是,使用后一种方法,您仍然需要使用硬编码值或reverse()来testingredirect目标。

希望这可以帮助。

Django提供了一个testing客户端,可以用来testing完整的请求/响应周期: 文档包含一个对给定url进行get请求的例子,以及断言状态码和模板上下文。 您还需要一个testing,它会执行一个POST并按照预期成功redirect。