views:

62

answers:

3

Is there a way to test the html from the response of:

response = self.client.get('/user/login/')

I want a detailed check like input ids, and other attributes. Also, how about sessions that has been set? is it possible to check their values in the test?

+3  A: 

Not sure, but take a look at http://docs.djangoproject.com/en/dev/topics/testing/#testing-responses.

response.context is maybe a way to check your values.

dzen
I guess this is my best option. thanks.
Marconi
The `context` won't necessarily contain the session unless the application puts the session into the context. Often, a better choice is to use assertContains to check the content of the page and check the tags.
S.Lott
That's fine, I decided not to test the session for now since what I was really after is what has been set in session once user is logged-in. Maybe later on when I have something important on the session to test.
Marconi
@Marconi: You **never** have something in the session to test. You only have things set in the session that are **visible behavior changes**. If there's no change in the application's behavior, the session value doesn't matter and there's nothing to test.
S.Lott
+1  A: 

Simon Willison's soup-select is a nice way to test the content of an HTML response based on jQuery-like CSS selectors. So, for example, to check that your page has an input with ID my_input_id:

from BeautifulSoup import BeautifulSoup as Soup
from soupselect import select
response = self.client.get('/user/login/')
soup = Soup(response.content)
self.assertEquals(len(select(soup, 'input#my_input_id')), 1)
Daniel Roseman
Often the assertContains already available in Django TestCases does this job more simply than introducing an external HTML parser.http://docs.djangoproject.com/en/1.1/topics/testing/#django.test.TestCase.assertContains
S.Lott
cool but I don't wanna use external stuff for now.
Marconi
+2  A: 

Careful.

Also, how about sessions that has been set? is it possible to check their values in the test?

TDD is about externally visible behavior. To see if the user has a session, you would provide a link that only works when the user is logged in and has a session.

The usual drill is something like the following.

class When_NoLogin( TestCase ):
    def test_should_not_get_some_resource( self ):
        response= self.client.get( "/path/that/requires/login" )
        self.assertEquals( 301, response.status_code )

That is, when not logged in, some (or all) URI's redirect to the login page.

class When_Login( TestCase ):
    def setUp( self ):
        self.client.login( username='this', password='that' )
    def test_should_get_some_resource( self ):
        response= self.client.get( "/path/that/requires/login" )
        self.assertContains( response, '<input attr="this"', status_code=200 )
        self.assertContains( response, '<tr class="that"', count=5 )

http://docs.djangoproject.com/en/1.2/topics/testing/#django.test.TestCase.assertContains

That is, when logged in, some (or all) URI's work as expected.

Further, the URI response contains the tags you require.

You don't test Django to see if it creates a session. Django already has unit tests for this. You test your application's externally visible behavior -- does it behave like there's a session? Are pages properly visible? Are they properly customized with session-specific information?

S.Lott
Thanks. I already know about those. I guess I just need to wrap my head around it since I've seen it in rails that you can test sessions and html tags from response/
Marconi
@Marconi: HTML Tags can be examined with assertContains. The session object itself is not externally visible and therefore cannot be part of a proper test. If Ruby unit testing exposes the session, something's really wrong with their approach. Testing a session object isn't very common for unit testing -- I don't know why they would expose this object to the test framework.
S.Lott