views:

42

answers:

3

Can I launch tests for my Django reusable app without incorporating this app to some project?

My app uses some models, so it is necessary to provide (TEST_)DATABASE_* settings. Where to store them and how to launch tests?

For django project I run tests by: manage.py test, when I use django-admin.py I get:

Error: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.

I believe this have to be very simple but I stucked with this.

What are the best practises here?

A: 

"Django project" have basically two files: settings.py and urls.py. Deleting urls.py shouldn't be a problem unless you are actually using it (ie. reverse function).

Riding out of settings.py would be much harder. You wouldn't be able to use ORM or any other Django components that depends on it. If so, you don't need Django stack and you can run your tests "normal way": http://docs.python.org/library/unittest.html

But, if you need Django stack ("DJANGO_SETTINGS_MODULE is undefined" means you need it), you also need settings.py. Probably the best solution for you would be to write generic settings.py file for all your applications (create empty project for that).

Then setup your INSTALLED_APPS this way:

INSTALLED_APPS = (
    ...
    os.environ['APP_TO_TEST'],
)

Then, if you want to test your app, go to directory with your generic settings.py file and type:

export APP_TO_TEST="my_app"
# /home/user/dev/my_app is directory with app
export PYTHONPATH="/home/user/dev/"
./manage.py test $APP_TO_TEST

If you need apps dependences in INSTALLED_APPS, you can add another variable.

Tomasz Wysocki
+2  A: 

For my reusable app(django-moderation) i use buildout. I create example_project, i use it with buildout to run tests on it. I simply put my app inside of settings of example_project.

When i want to install all dependencies used by my project and run tests, i only need to do following:

  • Run: python bootstrap.py
  • Run buildout:

    bin/buildout

  • Run tests for Django 1.1 and Django 1.2:

    bin/test-1.1 bin/test-1.2

Here you can find tutorial how to configure reusable app to use buildout for deployment and tests run: http://jacobian.org/writing/django-apps-with-buildout/

Here you will find example buildout config which i use in my project:

http://github.com/dominno/django-moderation/blob/master//buildout.cfg

Dominik Szopa
Thanks for useful info. Will see if this solves my problem (looks like a lot of hassle at a first glance) but might be interesting for other purposes.
Lukasz Dziedzia
A: 

I've ended with such solution (it was inspired by solution found in django-voting):

Create file eg. 'runtests.py' in tests dir containing:

import os, sys
from django.conf import settings

DIRNAME = os.path.dirname(__file__)
settings.configure(DEBUG = True,
                   DATABASE_ENGINE = 'sqlite3',
                   DATABASE_NAME = os.path.join(DIRNAME, 'database.db'),
                   INSTALLED_APPS = ('django.contrib.auth',
                                     'django.contrib.contenttypes',
                                     'django.contrib.sessions',
                                     'django.contrib.admin',
                                     'myapp',
                                     'myapp.tests',))


from django.test.simple import run_tests

failures = run_tests(['myapp',], verbosity=1)
if failures:
    sys.exit(failures)

It allows to run tests by python runtests.py command. It doesn't require installed dependencies (eg. buildout) and it doesn't harm tests run when app is incorporated into bigger project.

Lukasz Dziedzia