Test static resources in Django tests
02 June 2011
At Mozilla we use jingo-minify to bundle static resources such as
.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!