如何在Django视图不返回值时测试它们

时间:2017-09-11 20:16:10

标签: django unit-testing django-testing

我是Django的新手。我已经完成了一些教程,编写了一些模型,视图,表格等等,但是我不明白它们是如何被测试的,因为要么没有返回任何内容,要么返回的内容都是如此严格限制它没有&#39 ; t在测试方面有意义。

例如,这里有两个视图类:

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,不会返回任何内容。我怎么能检查这是否正常工作?

第二个函数有两个函数,但它们的返回值不是我可以用assert

测试的东西

我怎么能使用TDD方法来处理Django?

我以前习惯使用nunit和MS' unit' Visual Studio中的测试,模拟等

3 个答案:

答案 0 :(得分:3)

实际上,Django的泛型基于类的视图无缘无故被称为通用。

您可以查看ListViewCreateView的来源。

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)

返回有效的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 方法处理程序返回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))

这两种方法都返回有效的可测试的 Django响应。

总之,ListBlogPostViewCreateBlogPostView都可以在tests.py中直接测试。您只需要更详细地了解the implementation of Django's generic views即可。 开源的力量!

答案 1 :(得分:1)

测试view与函数不同,大部分时间都没有返回值。我这样做的方式是断言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>'))

对于拥有view的{​​{1}},您可以实际检查是否正在检索它并正确传递给查看。

context
  

我怎么能使用TDD方法来处理Django?

对于TDD,您只需在创建blogPost = BlogPost.object.get(id=1) self.assertEqual(response.context['blogPost'].name, blogPost.name) 视图之前先测试它。它实际上取决于您喜欢测试的细节并找到它的平衡。我更愿意主要测试html正在设置,context中的重要html元素。

答案 2 :(得分:0)

你仍然可以测试很多参数 -

  • 获取和发布请求的状态代码
  • 上下文数据中的变量(例如表单)
  • 断言使用的模板
  • 创建视图时在帖子请求上创建对象
  • 使用状态代码检查权限

关于django视图的测试是技术上的集成测试。只要您的测试足够精细,就意味着您不会在视图中测试表单或模型的代码,如果您遵循Classical TDD,我也不会发现任何问题。