Login

"Zoom in" on rendered HTML that the test client returns

Author:
peterbe
Posted:
April 21, 2009
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

If you have this as your base class for all unit tests you can do the following:

class TestViews(BaseTestCase):
    def test_generated_stats(self):
        "test that certain stuff in the response"

        ...create some content for testing or use fixtures...

        response = self.client.get('/some/page/')

        # At this point response.content is a huge string filled with HTML tags and
        # "junk" that you don't need for testing the content thus making it difficult
        # to debug the generated HTML because it so huge. 
        # So we can zoom in on the <div id="stats>...</div> node
        html = self._zoom_html(response.content, '#stats')

        # the variable 'html' will now be something like this:
        """
        <div id="stats">
            <p>
                <strong>2</strong> students<br/>
                <em>1</em> warning.
            </p>
        </div>
        """

        # This makes it easier to debug the response and easier to test
        # against but the HTML might still be in the way so this would fail:
        self.assertTrue('2 students' in html) # will fail

        # To strip away all html use _strip_html()
        content = self._strip_html(html)

        # Now this will work
        self.assertTrue('2 students' in content) # will work

It works for me and I find this very useful so I thought I'd share it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# python
import re
from cStringIO import StringIO
# django
from django.test import TestCase


class BaseTestCase(TestCase):

    def _zoom_html(self, html, css_selector):

        try:
            from lxml.html import parse
            from lxml import etree
            from lxml.cssselect import CSSSelector
        except ImportError:
            return html

        parser = etree.HTMLParser()
        tree = etree.parse(StringIO(html), parser)
        page = tree.getroot()

        if isinstance(css_selector, basestring):
            selector = CSSSelector(css_selector)
        else:
            raise ValueError("css_select must be a string")

        html_chunks = []
        for part in selector(page):
            html_chunks.append(etree.tostring(part, pretty_print=True))

        return ''.join(html_chunks)

    def _strip_html(self, html):
        return re.sub('</?\w.*?>', '', html)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 1 week ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 9 months, 4 weeks ago
  5. Help text hyperlinks by sa2812 10 months, 3 weeks ago

Comments

Please login first before commenting.