Python Developer and Educator
2008-07-15
./manage.py test
/myproject/myapp/tests.py
import unittest
And the models and model classes you're testing:
from myapp.models import RegistrationProfile, UserProfile
Create a class for the model to test:
class UserProfileTestCase(unittest.TestCase):
In that class, write a setUp method where you create a few objects with dummy data. Maybe it's obvious, but the k/v pairs you're passing in to create() should map to your model:
def setUp(self):
self.profile1 = UserProfile.objects.create(id=1, user_id=1, first_name='John',
last_name='Smith', address='123 Main Street', favorite_cheese='cheddar')
self.profile2 = UserProfile.objects.create(id=2, user_id=2, first_name='Jane',
last_name='Doe', address='23 Park Avenue', favorite_cheese='swiss')
Then write a second method to test assertions against these objects:
def test_something(self):
self.assertEquals(self.profile1.user_id, 1)
self.assertEquals(self.profile2.user_id, 2)
profile = UserProfile.objects.get(pk=1)
self.assertEquals(profile.first_name, 'John')
self.profile1.first_name = 'Mark'
self.assertNotEquals(self.profile1.first_name, 'John')
self.assertEquals(self.profile1.first_name, 'Mark')
Okay, so that wasn't such an exciting example, but it works.
url(r'^/accounts/register/$', views.register, name='myapp_register'),
Using the test client to GET '/accounts/register/' would in turn test the associated view method 'register', and any other methods that views.register has dependencies on.
.....
Start by importing the Client and TestCase modules:
from django.test import Client, TestCase
Create a class that extends TestCase (it doesn't matter what it's named):
class ViewTests(TestCase):
The first method just needs to instantiate the test client:
def setUp(self):
self.client = Client()
The second method is the test method - I named it for the corresponding view method it's testing, just for convenience:
def test_register(self):
response = self.client.get('/accounts/register/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Register Your Account')
response = self.client.post('/accounts/register/', {'username': 'myname', 'password': 'mypassword'})
self.assertEqual(response.status_code, 200)
For a much more detailed example, take a look at this piece of Django documentation: Testing using the Test Client
File "/Users/bshaurette/Code/django_trunk/django/core/handlers/base.py",
line 126, in get_response
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
TypeError: 'in ' requires string as left operand
I'm not sure why I needed to have an INTERNAL_IPS value set, but I didn't have it in my project's settings.py, so I added it to the top of the tests.py instead:
INTERNAL_IPS = ('127.0.0.1',)
After that, I hit an error related to a variable that couldn't be found in one of the project urls:
ImproperlyConfigured: Error while importing URLconf 'myproject.urls': 'MEDIA_LOCATION'
In the project's urls.py, one of the patterns included an environment variable - the location for media (style sheets):
(r'^site_media/(?P .*)$', 'django.views.static.serve', {'document_root': os.environ['MEDIA_LOCATION']})
So I also gave that variable a value in my test file:
os.environ['MEDIA_LOCATION'] = '/Users/myuser/myproject/media/'
Finally, I got this error:
DoesNotExist: Site matching query does not exist.
In my project's settings.py, I had the SITE_ID value set to '2' (I had been playing with different site values for my registration and confirmation emails earlier). Setting it back to '1' seemed to fix the problem:
SITE_ID = 1
Apparently, if that value is anything other than '1', your tests with the client won't run: Ticket #5979: Django tests fail if SITE_ID is not 1
My final tests.py for views looks something like this:
import os
from django.test import Client, TestCase
os.environ['MEDIA_LOCATION'] = '/Users/bshaurette/tippit/openmedia_project/public'
INTERNAL_IPS = ('127.0.0.1',)
class ViewTests(TestCase):
def setUp(self):
self.client = Client()
def test_register(self):
response = self.client.get('/accounts/register/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Register Your Account')
response = self.client.post('/accounts/register/', {'username': 'myname', 'password': 'mypassword'})
self.assertEqual(response.status_code, 200)
Contact: barbara@mechanicalgirl.com