views:

354

answers:

1

Hi!

I want to write a unit test that performs HTTP requests directly (instead of using django.test.client.Client).

If you're curious why - it's because I want to test a Thrift-over-HTTP API that I expose from my Django application - and I want to use the Thrift client in the unit test.

The problem is that during tests, the server is not actually being run. When using django.test.client.Client, it will simply call the view functions instead of actually making a HTTP request. (Please correct me if I'm wrong.)

So what would be the best way to force the test framework to start the HTTP server?

I tried writing a bash script that does something like this:

./manage.py testserver --addrport 7000 &
PID=$!
sleep 5
./manage.py test --no-input
kill $PID

But that is messy (and doesn't really work) because 1) I need the sleep (otherwise the test will start before the DB is initialized by the test server) and 2) the test will try to initialize the database again (after the testserver already initialized it).

Any other solutions to this?

Thank you.

+2  A: 

Yup, You're right - it's a problem and there is a bug for it: http://code.djangoproject.com/ticket/2879

Just, You might then encounter multithreaded problems, intentionally ommited: http://code.djangoproject.com/ticket/10117 http://code.djangoproject.com/ticket/4513 http://code.djangoproject.com/ticket/3357

I am frustrated, thus I wrote a library that includes starting live server in separate thread and cleaning it afterwards: http://devel.almad.net/trac/django-sane-testing/ . It also starts Django's server multithreaded by runtime monkeypatching and you can use cherrypy http instead (which is better anyway).

Only problem is it requires you to use nose as test framework (100% backward compatibility with standard unittest, but if you're already using something else...). You can then just use --with-django and --with-djangoliveserver/--with-cherrypyliveserver. No idea how it will work with thrift.

Just beware:

  • Please do not bug Django devs with bugreports, You're on your own
  • Windmill provides same solution, so if You're using windmill, You'll probably have port conflicts
Almad
Thanks for the nice answer! Sounds like overkill for me though. I guess I'll just go the easy way for now. Which would be: write a normal test (not Django - so it doesn't mess the DB), which connects to the test server, that should be started beforehand. In the test setUp, if connection fails, display a nice message like "please start your Django test server". :)
ionut bizau