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
-~----------~----~----~----~------~----~------~--~---

Reply via email to