Django testing the html of your homepage against the content of a response
Asked Answered
J

1

6

If I have a test like so...

 def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        expected_html = render_to_string('home.html', request=request)
        self.assertEqual(response.content.decode(), expected_html)

As soon as I add a form in curly braces, e.g. {{ form }} The above test will fail as the .html file will not render the form only the response will. Thus causing the assertion to not match. Is there a way round this so that I can still test my html against the response?

Jonijonie answered 21/5, 2016 at 12:54 Comment(2)
render_to_string supports a dictionary as second parameter or using context keyword which will be used as context to render the template. You will have to send the form in the context dictionary. See django docsConfabulation
This seems a bit of a strange test though. It seems you're duplicating the code of the view, then checking they give the same result. Why? What is this supposed to be testing?Anglophile
C
27

You can pass a form instance to the render_to_string function:

from django.template import RequestContext
from django.template.loader import render_to_string

form = ModelForm()
context = RequestContext(request, {'form': form})
expected_html = render_to_string('home.html', context)

Usually what I do is splitting this kind of test into several other tests, like this:

Using from django.test import TestCase

def setUp(self):
    self.user = User.objects.create_user('john', '[email protected]', '123')
    self.client.login(username='john', password='123')
    self.response = self.client.get(r('home'))

First test which template was used:

def test_template(self):
    self.assertTemplateUsed(self.response, 'home.html')

Test the form:

def test_has_form(self):
    form = self.response.context['form']
    self.assertIsInstance(form, CreateModelForm)

And then I test the key parts of the HTML:

def test_html(self):
    self.assertContains(self.response, '<form')
    self.assertContains(self.response, 'type="hidden"', 1)
    self.assertContains(self.response, 'type="text"', 2)
    self.assertContains(self.response, 'type="radio"', 3)
    self.assertContains(self.response, 'type="submit"', 1)

Finally if the rendered template has a csrf token:

def test_csrf(self):
    self.assertContains(self.response, 'csrfmiddlewaretoken')
China answered 21/5, 2016 at 14:28 Comment(1)
When I do response.context['form'] , it says form is an invalid key. Are you manually setting it some where?Demurral

© 2022 - 2024 — McMap. All rights reserved.