Opened 3 years ago

Last modified 18 months ago

#20456 assigned New feature

Easier unit testing for class-based views

Reported by: Benoît Bryon Owned by: Asif Saifuddin Auvi
Component: Testing framework Version: master
Severity: Normal Keywords: cbv test
Cc: bmispelon@…, marc.tamlyn@…, Natim, unai@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

When django users create class-based views, they create custom code. Testing this code matters. Writing unit tests for the custom code (and only for the custom code) is important.

As of Django 1.5, the easiest way to test class-based views is using the builtin test client. But it performs integration tests, i.e. involves middlewares, URL resolvers, decorators...
It is also quite easy to use django.test.RequestFactory and as_view() classmethod. But, since as_view() returns a function, the tests can only check the response. It means the class-based views are tested as a system.

It seems that writing unit tests is possible, i.e. we can write unit tests for class-based views methods.
There is at least one technique which was presented at DjangoCon Europe 2013 Warsaw:

The recipe mentioned above seems to work (to be confirmed). But wouldn't be better if the recipe was documented in Django's documentation (https://docs.djangoproject.com/en/1.5/topics/testing/advanced/ I guess) and tools (setup_view) were builtin Django?

Note: perhaps, it would be even better if setup_view() is not a standalone function but is a method of View class. Something like as_view(), but which returns an instance.

Change History (11)

comment:1 Changed 3 years ago by Baptiste Mispelon

Cc: bmispelon@… added
Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:2 Changed 3 years ago by Marc Tamlyn

Cc: marc.tamlyn@… added
Keywords: cbv test added
Owner: changed from nobody to Marc Tamlyn
Status: newassigned
Triage Stage: UnreviewedAccepted

Accepted in principle, not necessarily the design.

comment:3 Changed 3 years ago by Natim

Cc: Natim added

comment:4 Changed 3 years ago by Benoît Bryon

I have 2 use cases for this feature:

  • As a library developer, I want to test generic class-based views without having to register them in URLconf.
  • As a project developer, given I override some generic class-based view in order to customize something (such as "get_template_names" or "get_context_data" methods), I want to test only the methods I overrid (I suppose other methods are covered elsewhere).

Here is an example TestCase in django-downloadview: https://github.com/benoitbryon/django-downloadview/blob/6dd090757a8aaad72f9195d22c7933ae97f02a7d/django_downloadview/tests/views.py#L208
The idea is that PathDownloadView customizes get_file() method, so, I want to test that. Notice that django-downloadview is a library that does not provide URLconf, so I appreciate to test views without having to setup some fake URLconf.

comment:5 Changed 3 years ago by Benoît Bryon

Perhaps this feature would make it possible to simplify tests around Django's generic views:

comment:6 Changed 3 years ago by Unai Zalakain

Cc: unai@… added

comment:7 Changed 3 years ago by anonymous

How about something like MyCBView.as_object(request, *args, **kwargs) instead of the setup_view approach?

comment:8 Changed 3 years ago by Baptiste Mispelon

Has patch: set

Someone made a proposal here: https://github.com/django/django/pull/2368/

comment:9 Changed 2 years ago by Tim Graham

Patch needs improvement: set

comment:10 Changed 19 months ago by Asif Saifuddin Auvi

Hi Marc what are the tasks remaining to get this ticket merged? If you don't have time let me do the rest on behalf of you

comment:11 Changed 18 months ago by Asif Saifuddin Auvi

Owner: changed from Marc Tamlyn to Asif Saifuddin Auvi
Note: See TracTickets for help on using tickets.
Back to Top