Kwissle

My real-time quiz battle game Kwissle.com

Crosstips.org

My fun Crossword solver project. Crosstips.org & Krysstips.se

Kung Fu

Fujian White Crane Kung Fu

Photos

Photoalbum, both old and new.

Twitter

Follow me on Twitter

Contact me

My contact details and how to contact me.

 

KungFuPeople.com
Do you train Kung Fu?
Or know someone who does?
Then check out KungFuPeople.com


Mobile version of this page Mobile version of this page


 
Django

Test static resources in Django tests


2nd of June 2011

At Mozilla we use jingo-minify to bundle static resources such as .js and .css files. It's not a perfect solution but it's got some great benefits. One of them is that you need to know exactly which static resources you need in a template and because things are bundled you don't need to care too much about what files it originally consisted of. For example "jquery-1.6.2.js" + "common.js" + "jquery.cookies.js" can become "bundles/core.js"

A drawback of this is if you forget to compress and prepare all assets (using the compress_assets management command in jingo-minify) is that you break your site with missing static resources. So how to test for this?

Here's a simple solution I cooked up which appears to do the trick. It's just a quick start but it works. First:

 # tests/mixins.py
 import re
 from nose.tools import eq_, ok_

 SCRIPTS_REGEX = re.compile('<script\s*[^>]*src=["\']([^"\']+)["\'].*?</script>',
                           re.M|re.DOTALL)
 STYLES_REGEX = re.compile('<link.*?href=["\']([^"\']+)["\'].*?>',
                          re.M|re.DOTALL)

 class EmbedsTestCaseMixin:
    def assert_all_embeds(self, response):
        if hasattr(response, 'content'):
            response = response.content
        response = re.sub('<!--(.*)-->', '', response, re.M)
        for found in SCRIPTS_REGEX.findall(response):
            if found.endswith('.js'):
                resp = self.client.get(found)
                eq_(resp.status_code, 200, found)

        for found in STYLES_REGEX.findall(response):
            if found.endswith('.css'):
                resp = self.client.get(found)
                eq_(resp.status_code, 200, found)

Then with this you can render a page and check that all resources are reachable:

 # apps/foo/tests.py
 from tests.mixins import EmbedsTestCaseMixin
 from django.test import TestCase
 from django.core.urlresolvers import reverse

 class FooViewsTestCase(TestCase):
     def test_add_page_static_files(self):
          url = reverse('foo.views.add_page')
          response = self.client.get(url)
          assert response.status_code == 200
          self.assert_all_embeds(response)

I know it ain't django-rocket science but it's damn useful as it quickly catches me out if I accidentally get a typo in any of the bundles which in previous projects I've become accustomed to check by simply clicking around in Firefox with Firebug (Net tab) open.

Hope it helps!



Comment

Alex - 11th July 2011  [«« Reply to this]
Your comment-removing regex is a bit too greedy: it will eat anything between two comments:

In [10]: re.sub('<!--(.*)-->', '', '<!-- lala -->lu<!-- blah -->', re.M)
Out[10]: ''

fix: use the non-greedy version of *:

In [11]: re.sub('<!--(.*?)-->', '', '<!-- lala -->lu<!-- blah -->', re.M)
Out[11]: 'lu'
Peter Bengtsson - 11th July 2011   [«« Reply to this]
Thanks! Well spotted!
 
Name:
Email:
hide my email address.

Your email address will be encoded to prevent email-extraction spiders from reading it so you won't get spammed if you decide to show your email address.