当 Django 视图没有 return 值时如何测试它们
How do I test Django views when they don't return values
我是 Django 的新手。我已经学习了一些教程,编写了一些模型、视图、表单等,但我不明白如何测试它们,因为要么没有 returned,要么 returned 就是如此紧密结合它在测试方面没有意义。
例如这里有两个视图 类:
class ListBlogPostView(ListView):
model = BlogPost
template_name = 'app/blogpost_list.html'
class CreateBlogPostView(CreateView):
model = BlogPost
template_name = 'app/blogpost_edit.html'
form_class = BlogPostForm
def get_success_url(self):
return reverse('blogpost-list')
def get_context_data(self, **kwargs):
context = super(CreateBlogPostView, self).get_context_data(**kwargs)
context['action'] = reverse('blogpost-new')
return context
第一个 ListBlogPostView 没有 return 任何东西。我怎样才能检查它是否正常工作?
第二个有几个函数,但它们的 return 值不是我可以用 assert
测试的东西
我怎么能对 Django 使用 TDD 方法?
我习惯在 Visual Studio 中使用 nunit 和 MS 'unit' 测试,模拟等
实际上,Django 的 generic class-based 视图没有理由不被称为 generic。
您可以查看两者的来源ListView
and CreateView
。
ListView
有一个 GET 方法处理程序:
class BaseListView(MultipleObjectMixin, View):
"""A base view for displaying a list of objects."""
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty:
# ...
context = self.get_context_data()
return self.render_to_response(context)
哪个 return 是一个有效的 Django 响应并且可以在 tests.py
中测试。
如果您查看 CreateView
,它继承自 BaseCreateView
(就像 ListView
继承自 BaseListView
):
class BaseCreateView(ModelFormMixin, ProcessFormView):
"""
Base view for creating an new object instance.
Using this base class requires subclassing to provide a response mixin.
"""
def get(self, request, *args, **kwargs):
# ...
def post(self, request, *args, **kwargs):
# ...
也继承自ProcessFormView
:
class ProcessFormView(View):
"""Render a form on GET and processes it on POST."""
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
GET 请求将产生有效响应。如您所见,此处的 POST 方法处理程序 return 是 self.form_valid(form)
或 self.form_invalid(form)
,具体取决于表单状态。
这两个方法的源码见ViewMixin
:
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(self.get_context_data(form=form))
这两种方法 return 一个有效的 可测试 Django 响应。
总之,你的ListBlogPostView
和CreateBlogPostView
都可以直接在tests.py
中测试。您只需要更详细地查看 the implementation of Django's generic views。 开源的力量!
测试 view
与函数不同,大多数时候不会有 return 值。我这样做的方法是断言 html
响应。
所以对于 ListBlogPostView
这取决于 blogpost_list.html
模板中的内容。
一般视图测试应如下所示:
class ListBlogPostViewTest(TestCase):
def test_blogpost_list_view(self):
response = self.client.get(reverse('blogpost-list'))
html = response.content.decode('utf8')
self.assertTrue(html.startswith('<html>'))
self.assertIn('<title>BlogPost lists</title>', html)
self.assertTrue(html.endswith('</html>'))
对于具有 context
的 view
,您实际上可以检查它是否正在被检索并正确传递给查看。
blogPost = BlogPost.object.get(id=1)
self.assertEqual(response.context['blogPost'].name, blogPost.name)
How could I ever use a TDD approach to Django?
至于 TDD,您只需在创建视图之前先测试 html
视图即可。这实际上取决于您喜欢测试的细节并找到平衡点。我更喜欢主要测试正在设置的 context
并且重要的 html
元素在 view
.
中
你仍然可以肯定地测试很多参数-
- 获取和 post 请求的状态代码
- 上下文数据(例如表单)中的变量
- 使用断言模板
- 在创建视图
的情况下根据 post 请求创建对象
- 使用状态代码检查权限
问题是对 Django 视图的测试在技术上是集成测试。只要您的测试足够细化,就意味着您不会在视图中测试表单或模型的代码,如果您遵循经典 TDD,我看不出有任何问题。
我是 Django 的新手。我已经学习了一些教程,编写了一些模型、视图、表单等,但我不明白如何测试它们,因为要么没有 returned,要么 returned 就是如此紧密结合它在测试方面没有意义。
例如这里有两个视图 类:
class ListBlogPostView(ListView):
model = BlogPost
template_name = 'app/blogpost_list.html'
class CreateBlogPostView(CreateView):
model = BlogPost
template_name = 'app/blogpost_edit.html'
form_class = BlogPostForm
def get_success_url(self):
return reverse('blogpost-list')
def get_context_data(self, **kwargs):
context = super(CreateBlogPostView, self).get_context_data(**kwargs)
context['action'] = reverse('blogpost-new')
return context
第一个 ListBlogPostView 没有 return 任何东西。我怎样才能检查它是否正常工作?
第二个有几个函数,但它们的 return 值不是我可以用 assert
测试的东西我怎么能对 Django 使用 TDD 方法?
我习惯在 Visual Studio 中使用 nunit 和 MS 'unit' 测试,模拟等
实际上,Django 的 generic class-based 视图没有理由不被称为 generic。
您可以查看两者的来源ListView
and CreateView
。
ListView
有一个 GET 方法处理程序:
class BaseListView(MultipleObjectMixin, View):
"""A base view for displaying a list of objects."""
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty:
# ...
context = self.get_context_data()
return self.render_to_response(context)
哪个 return 是一个有效的 Django 响应并且可以在 tests.py
中测试。
如果您查看 CreateView
,它继承自 BaseCreateView
(就像 ListView
继承自 BaseListView
):
class BaseCreateView(ModelFormMixin, ProcessFormView):
"""
Base view for creating an new object instance.
Using this base class requires subclassing to provide a response mixin.
"""
def get(self, request, *args, **kwargs):
# ...
def post(self, request, *args, **kwargs):
# ...
也继承自ProcessFormView
:
class ProcessFormView(View):
"""Render a form on GET and processes it on POST."""
def get(self, request, *args, **kwargs):
"""Handle GET requests: instantiate a blank version of the form."""
return self.render_to_response(self.get_context_data())
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
GET 请求将产生有效响应。如您所见,此处的 POST 方法处理程序 return 是 self.form_valid(form)
或 self.form_invalid(form)
,具体取决于表单状态。
这两个方法的源码见ViewMixin
:
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(self.get_context_data(form=form))
这两种方法 return 一个有效的 可测试 Django 响应。
总之,你的ListBlogPostView
和CreateBlogPostView
都可以直接在tests.py
中测试。您只需要更详细地查看 the implementation of Django's generic views。 开源的力量!
测试 view
与函数不同,大多数时候不会有 return 值。我这样做的方法是断言 html
响应。
所以对于 ListBlogPostView
这取决于 blogpost_list.html
模板中的内容。
一般视图测试应如下所示:
class ListBlogPostViewTest(TestCase):
def test_blogpost_list_view(self):
response = self.client.get(reverse('blogpost-list'))
html = response.content.decode('utf8')
self.assertTrue(html.startswith('<html>'))
self.assertIn('<title>BlogPost lists</title>', html)
self.assertTrue(html.endswith('</html>'))
对于具有 context
的 view
,您实际上可以检查它是否正在被检索并正确传递给查看。
blogPost = BlogPost.object.get(id=1)
self.assertEqual(response.context['blogPost'].name, blogPost.name)
How could I ever use a TDD approach to Django?
至于 TDD,您只需在创建视图之前先测试 html
视图即可。这实际上取决于您喜欢测试的细节并找到平衡点。我更喜欢主要测试正在设置的 context
并且重要的 html
元素在 view
.
你仍然可以肯定地测试很多参数-
- 获取和 post 请求的状态代码
- 上下文数据(例如表单)中的变量
- 使用断言模板
- 在创建视图 的情况下根据 post 请求创建对象
- 使用状态代码检查权限
问题是对 Django 视图的测试在技术上是集成测试。只要您的测试足够细化,就意味着您不会在视图中测试表单或模型的代码,如果您遵循经典 TDD,我看不出有任何问题。