#20456 closed New feature (fixed)
Easier unit testing for class-based views
Reported by: | Benoît Bryon | Owned by: | Felipe Lee |
---|---|---|---|
Component: | Testing framework | Version: | dev |
Severity: | Normal | Keywords: | cbv test |
Cc: | bmispelon@…, marc.tamlyn@…, Rémy Hubscher, unai@…, Sergey Fedoseev | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
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:
- 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.
Change History (21)
comment:1 by , 12 years ago
Cc: | added |
---|
comment:2 by , 12 years ago
Cc: | added |
---|---|
Keywords: | cbv test added |
Owner: | changed from | to
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 11 years ago
Cc: | added |
---|
comment:4 by , 11 years ago
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 by , 11 years ago
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
comment:6 by , 11 years ago
Cc: | added |
---|
comment:7 by , 11 years ago
How about something like MyCBView.as_object(request, *args, **kwargs) instead of the setup_view approach?
comment:8 by , 11 years ago
Has patch: | set |
---|
Someone made a proposal here: https://github.com/django/django/pull/2368/
comment:9 by , 10 years ago
Patch needs improvement: | set |
---|
comment:12 by , 8 years ago
Any update on this? I'm planning on moving to CBVs but this is concerning for my testing needs.
comment:13 by , 8 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
I don't see anyone actively working on it. Feel free to work on it if you like.
comment:14 by , 6 years ago
Cc: | added |
---|
comment:15 by , 5 years ago
Owner: | set to |
---|---|
Status: | new → assigned |
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.
comment:16 by , 5 years ago
Patch needs improvement: | unset |
---|
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
comment:19 by , 5 years ago
Patch needs improvement: | set |
---|
A few adjustments to the docs PR suggested but looking good.
comment:20 by , 5 years ago
Patch needs improvement: | unset |
---|
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.
comment:21 by , 5 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Accepted in principle, not necessarily the design.