On 12 Jul 2006, at 02:28, Malcolm Tredinnick wrote:
> I approached things from a different direction, though, more
> concentrating on how to unit test templates and views (as in not
> requiring a full end-to-end application setup in order to test
> them). So
> it's actually a orthogonal to what you are proposing here and fits in
> nicely.
I've been thinking about unit testing templates and views on-and-off
for the past few months. Here's the bulk of my thinking.
The best way of running tests against a Django application, to my
mind, is to run a "fake" web server (i.e. one that doesn't actually
bind to a port) around the application. This fake server acts as a
test harness. Tests can then create HttpRequest objects (probably a
subclass called something like TestHttpRequest), pass them to the
Django application, get back an HttpResponse object and run
assertions against that.
There's just one problem with this approach: while running assertions
against an HttpResponse object is adequate, the ideal situation would
be to run assertions against the template context as well. If you
just run assertions against the HttpResponse object you end up having
to process the HTML in some way to work out if the test has passed.
What you really want to be able to do is this (pseudocode):
send_get('/polls/1/')
assert_response_status(200)
assert_response_contains('This is poll 1')
assert_template_rendered('poll_detail.html')
assert_template_context_match('poll.id', 1)
assert_template_context_match('poll.title', 'poll 1')
(These function names are deliberately horrible - I haven't thought
about a nice API for this yet).
The first line above fakes sending a GET request to /polls/1/. The
next line checks that the response status code was 200, and the line
after checks that the response body contained 'This is poll 1'. So
far, all of these things can be done just using an HttpResponse object.
The next three lines assert that the correct template was rendered,
and check that the template context contained the expected data. This
isn't possible with just an HttpResponse - the template and context
have been rendered and forgotten by the time the HttpResponse is
returned.
TurboGears and Rails don't have this problem (in fact Rails is where
the idea for running assertions against the template context comes
from) because they couple their template systems to the view. We
don't want to do that in Django.
The solution I've been thinking about involves Django's event
dispatch system. I think we should be firing an event when a template
is rendered. The testing harness can then listen out for that event
and use it to capture the template and context, meaning you can run
assertions against them. This keeps our template system decoupled
while letting us write tests against the template activity within the
view functions.
I hope the above makes sense. I'll try to follow up later with a
better idea of how I think the assertions API should look.
Cheers,
Simon
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-developers
-~----------~----~----~----~------~----~------~--~---