Unit Testing in Django
Saturday, July 26th, 2008This article will be based off this bit of documentation:
http://www.djangoproject.com/documentation/testing/
To begin, I would like to give an introduction to unit tests. Unit tests are bits of testing code to test the functionality of your code. The reason why they are helpful is because say you change your model to have a non-null field of something new. You don’t change the controller method that creates the new entry – what happens? It’ll most likely fail. I don’t know about you, but I’d rather catch the tests early, instead of much later and all. This is where unit tests come in. Unit tests help give a bit more measure of success on that your methods actually will work.
They are extremely important.
Django utilizes both doctests, and unit tests. Personally I feel unit tests are a bit better because doc tests can clutter your code, making things a bit harder to read. To start a unit test all you need to do is something like:
from django.test import TestCase
class myTest(TestCase):
def test1(self):
…
The kicker that got me, and the majority of the reason why I’m posting this is that you absolutely need to have each method definition starting with test. If you have def foo, instead of the above – Your tests WILL NOT RUN I wish the documentation went over that bit of information.
Another important thing with testing is the ability to utilize fixture data. The problem I see is that I don’t want to use the fixture initial_data, because if I do that, then whenever I do a syncdb I may get data I really don’t want for my own development. Personally, I rather have my own fixture just for the unit tests. You can define that like this:
from django.test import TestCase
class myTest(TestCase):
fixtures = ['myfixture.json']
def test1(self):
…
Another thing I read about, that should be kept in mind that if your tests aren’t found, make sure that you have a models.py in the same directory. If you don’t, then apparently the tests aren’t found. It’s been reported, I don’t know the status of the issue (I haven’t run into the issue quite yet).
Now about functional tests…
Functional tests, as an introduction, is the testing of the flow of your site. For example, if you view the index of your site – do you get an error page? This is important to know, which is why functional tests are there. Unlike unit, this isn’t testing any one particular method – bit more to make sure that if a user was to visit your site in that area, that the behavior is expected.
Definitions for functional tests are exactly that of the unit tests, except a nifty little thing called the django test client. One example of how to use it is like this:
class functionalTests(TestCase):
fixtures = ['myfixture.json']
def testSiteIndex(self):
response = self.client.get(‘/’)
self.failUnlessEqual(response.status_code, 200)
So what this does is load up its own little browser so to speak and visit the index. If it’s successful, then the return is 200 and all is good.
The documentation goes over a bit more on functional tests – including post variables. You can use tests to make sure that posting something to the site works. Also, logging in and out and content checks also work.
I think unit testing, in general, is really quite good with DJango. I’ve read a few posts about how horrible it was, but I really feel it’s right in line with what Rails can do. There aren’t many nifty projects quite yet though, like automated unit testing and all – but that’ll come in time. There is one article I started reading about automated unit testing with python, I’ll post more on that later.





