Packaging Django apps
Packaging Django-aware libraries for distribution
Packaging apps so that they can be tested within a django context, but without having to add them to an existing django project is pretty easy to to, but takes a bit more work than a standalone application.
We recently pushed our django-errordite and python-errordite apps to PyPI, and as part of that process I was keen to ensure that we followed all the best practices.
I have a lot to learn about the Python community, so there's plenty I will have missed, and one area where I did come unstuck was that of testing.
In order to be a good citizen I was keen to ensure that the packages had good, if not complete, test coverage. When packaging the basic python version, python-errordite, it was easy to include tests, and have them run from the command line using the default Python unittest test runner.
The Django version presented a bit more of a challenge, as in order to use the default django test runner you need to running inside a django context - using manage.py (django_admin.py) and picking up a valid settings file. In addition, the django test runner runs tests within 'apps', and our package wasn't designed as an app (it has no models, and is a helper library that is django-aware, as opposed to a django app). What to do?
The solution that I have come up with (and I am happy to be corrected - remember I'm new to all this) is to include a mock django app and minimal settings file. The structure of the package is as follows:
$ tree
.
├── LICENCE.md
├── MANIFEST.in
├── README.rst
├── django_errordite
│ ├── __init__.py
│ └── handlers.py
├─* manage.py
├── setup.py
└─* test_app
├─* __init__.py
├─* models.py
├─* settings.py
└─* tests.py
Those files that are marked with a '*' are the django files - the tests sit within an app that contains no models, but is included in the standard INSTALLED_APPS
tuple within the settings.py
file:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'test_app',
)
The tests can now be run from the command line using standard django tests:
$ python manage.py test test_app
If anyone has any better ideas (people have mentioned 'nose' to me, but I haven't investigated that) please chip in - the more help the better!
Making Freelance Work
Posted in: django