Search code examples
pythondjangounit-testingdjango-cmsdjango-sekizai

Django unit testing Sekizai and django cms


How can I write tests in django ? I read the documentation : https://docs.djangoproject.com/en/dev/topics/testing/overview/

But we use django-cms and sekizai so when I do a simple test like:

from django.test import TestCase
from django.test.client import Client

class AccessTest(TestCase):
    def setUp(self):
        # Every test needs a client.
        self.client = Client()

    def test_details(self):
        # Issue a GET request.
        response = self.client.get('/')

        # Check that the response is 200 OK.
        self.assertEqual(response.status_code, 200)

I get this error :

Traceback (most recent call last):   File "/home/maazza/PycharmProjects/django_my_app/search_engine/tests.py", line 18, in test_details
    response = self.client.get('/')   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/client.py", line 439, in get
    response = super(Client, self).get(path, data=data, **extra)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/client.py", line 244, in get
    return self.request(**r)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/client.py", line 381, in request
    response = self.handler(environ)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/client.py", line 84, in __call__
    response = self.get_response(request)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 153, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 228, in handle_uncaught_exception
    return callback(request, **param_dict)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/views/defaults.py", line 33, in server_error
    return http.HttpResponseServerError(t.render(Context({})))   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/base.py", line 140, in render
    return self._render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/utils.py", line 62, in instrumented_test_render
    return self.nodelist.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/base.py", line 823, in render
    bit = self.render_node(node, context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node
    return node.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/utils.py", line 62, in instrumented_test_render
    return self.nodelist.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/base.py", line 823, in render
    bit = self.render_node(node, context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node
    return node.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/test/utils.py", line 62, in instrumented_test_render
    return self.nodelist.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/base.py", line 823, in render
    bit = self.render_node(node, context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/django/template/debug.py", line 74, in render_node
    return node.render(context)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/classytags/core.py", line 106, in render
    return self.render_tag(context, **kwargs)   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/sekizai/templatetags/sekizai_tags.py", line 74, in render_tag
    if not validate_context(context):   File "/home/maazza/.virtualenvs/django_my_app/local/lib/python2.7/site-packages/sekizai/templatetags/sekizai_tags.py", line 28, in validate_context
    "You must enable the 'sekizai.context_processors.sekizai' template " TemplateSyntaxError: You must enable the 'sekizai.context_processors.sekizai' template context processor or use 'sekizai.context.SekizaiContext' to render your templates. 

You must enable the 'sekizai.context_processors.sekizai'

Concerning this part I have sekizai.context_processors.sekizai in my TEMPLATE_CONTEXT_PROCESSORS.


Solution

  • http://racingtadpole.com/blog/testing-django-cms-sites/

    This was confusing because I was using sekizai correctly in my template.

    This post pointed me in the right direction here. The problem was Django was raising an exception but I was never getting to see it – just this much less helpful message.

    This Stackoverflow post explained how to enable logging of errors. I copied in the changes to settings.py, wrapping them inside the if 'test' statement.

    Then when I ran

    ./manage.py test

    I got a much more useful error message: I had forgotten to set up a table that my template was assuming would exist. Easily fixed!

    Hope that helps someone else.

    I needed to add some fixtures for it to work.

    EDIT: Ok after a lot of research I found out that despite the above blog I had a different problem.

    Thanks to this answer and this doc I knew I had to do it like this :

    from django.test import TestCase
    from django.test.client import Client
    from cms.test_utils.testcases import CMSTestCase
    from django.test.utils import override_settings
    from cms.models import Page
    from django.contrib import admin
    from django.conf.urls import url, patterns, include
    from django.conf import settings
    
    urlpatterns = patterns('',
        url(r'^admin/', include(admin.site.urls)),
        url(r'^search_engine/', include('search_engine.urls')),
        url(r'', include('cms.urls')),
    )
    
    
    class AccessTest(CMSTestCase):
    
        def setUp(self):
            # Every test needs a client.
            p = Page.objects.create(site_id=settings.SITE_ID, template='home_page.html')
            p.publish()
            self.client = Client()
    
        @override_settings(ROOT_URLCONF='search_engine.tests')
        def test_details(self):
            # Issue a GET request.
            response = self.client.get('/')
    
            # Check that the response is 200 OK.
            self.assertEqual(response.status_code, 200)
    

    How to unit test Django-CMS extensions? and http://docs.django-cms.org/en/latest/extending_cms/testing.html <= somehow this is only readable in 'lastest'

    8.1.1. Resolving View Names

    Your apps need testing, but in your live site they aren’t in urls.py as they are attached to a CMS page. So if you want to be able to use reverse() in your tests, or test templates that use the url template tag, you need to hook up your app to a special test version of urls.py and tell your tests to use that.

    So you could create myapp/tests/test_urls.py with the following code:

    from django.contrib import admin from django.conf.urls import url, patterns, include

    urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^myapp/', include('myapp.urls')), url(r'', include('cms.urls')), )

    And then in your tests you can plug this in with the override_settings() decorator:

    from django.test.utils import override_settings from cms.test_utils.testcases import CMSTestCase

    class MyappTests(CMSTestCase):

    @override_settings(ROOT_URLCONF='myapp.tests.test_urls')
    def test_myapp_page(self):
        test_url = reverse('myapp_view_name')
        # rest of test as normal
    

    If you want to the test url conf throughout your test class, then you can use apply the decorator to the whole class:

    from django.test.utils import override_settings from cms.test_utils.testcases import CMSTestCase

    @override_settings(ROOT_URLCONF='myapp.tests.test_urls') class MyappTests(CMSTestCase):

    def test_myapp_page(self):
        test_url = reverse('myapp_view_name')
        # rest of test as normal