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:
* http://tech.novapost.fr/static/images/slides/djangocon-europe-2013-unit-
test-class-based-views.html
* http://tech.novapost.fr/django-unit-test-your-views-en.html
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: bmispelon@… (added)
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:1>
* owner: nobody => mjtamlyn
* keywords: => cbv test
* status: new => assigned
* cc: marc.tamlyn@… (added)
* stage: Unreviewed => Accepted
Comment:
Accepted in principle, not necessarily the design.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:2>
* cc: Natim (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:3>
Comment (by benoitbryon):
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:4>
Comment (by benoitbryon):
Perhaps this feature would make it possible to simplify tests around
Django's generic views:
* perhaps tests such as
https://github.com/django/django/blob/a71ff762356a46f37d189f503f0ec2aaaca6ad0e/tests/generic_views/test_base.py#L231
could be simplified
* perhaps
https://github.com/django/django/blob/a71ff762356a46f37d189f503f0ec2aaaca6ad0e/tests/generic_views/urls.py
could be removed
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:5>
* cc: unai@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:6>
Comment (by anonymous):
How about something like MyCBView.as_object(request, *args, !**kwargs)
instead of the setup_view approach?
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:7>
* has_patch: 0 => 1
Comment:
Someone made a proposal here: https://github.com/django/django/pull/2368/
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:8>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:9>
Comment (by auvipy):
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
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:10>
* owner: mjtamlyn => auvipy
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:11>
Comment (by Eron Lloyd):
Any update on this? I'm planning on moving to CBVs but this is concerning
for my testing needs.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:12>
* status: assigned => new
* owner: Marc Tamlyn => (none)
Comment:
I don't see anyone actively working on it. Feel free to work on it if you
like.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:13>
* cc: Sergey Fedoseev (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:14>
* owner: (none) => Felipe Lee
* status: new => assigned
Comment:
Looks like there's a repo out there that has a TestCase set up to make
testing CBVs easier: https://github.com/revsys/django-test-
plus/blob/master/test_plus/test.py#L386
Seems like a good starting point. There's some things about that
implementation that I'll probably change a bit. I'll also remove some
methods that are very specific to that repo's testing classes.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:15>
* needs_better_patch: 1 => 0
Comment:
Brought this ticket up on django developers forum to determine path
forward: https://groups.google.com/forum/#!topic/django-
developers/IxesUYH5b6A
Based on feedback, implemented changes based on the pr that had been
proposed a few comments ago (years ago). New pull request:
https://github.com/django/django/pull/11908
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:16>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"31d1822532d716d5b2f1422372d07dd05067bfc6" 31d18225]:
{{{
#!CommitTicketReference repository=""
revision="31d1822532d716d5b2f1422372d07dd05067bfc6"
Refs #20456 -- Added test for initialization of request/args/kwargs
attributes in View.Setup().
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:17>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"c2c27867ef1d4ad32369f8cda42a6d72b262cae5" c2c27867]:
{{{
#!CommitTicketReference repository=""
revision="c2c27867ef1d4ad32369f8cda42a6d72b262cae5"
Refs #20456 -- Moved initialization of HEAD method based on GET to the
View.setup() for generic views.
This will ease unit testing of views since setup will essentially do
everything needed to set the view instance up (other than instantiating
it). Credit for idea goes to Vincent Prouillet.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:18>
* needs_better_patch: 0 => 1
Comment:
A few adjustments to [https://github.com/django/django/pull/11942 the docs
PR] suggested but looking good.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:19>
* needs_better_patch: 1 => 0
Comment:
Made the change a bit ago but I forgot I needed to come in here to remove
the "Patch needs improvement" flag. Sorry about that.
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:20>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:21>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"a2e96f7969059fb4e621a1cd591fbdd0d4deae2e" a2e96f79]:
{{{
#!CommitTicketReference repository=""
revision="a2e96f7969059fb4e621a1cd591fbdd0d4deae2e"
Fixed #20456 -- Added example of directly testing CBVs in topics docs.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:22>
Comment (by Carlton Gibson <carlton.gibson@…>):
In [changeset:"87483757c80e76ea85586f2cb81bdfa1976d10e2" 87483757]:
{{{
#!CommitTicketReference repository=""
revision="87483757c80e76ea85586f2cb81bdfa1976d10e2"
[3.0.x] Fixed #20456 -- Added example of directly testing CBVs in topics
docs.
Backport of a2e96f7969059fb4e621a1cd591fbdd0d4deae2e from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20456#comment:23>