You aren't the first person to have this need: this is logged as
ticket #7835. The problem exists for any project that works at the
meta level, working on models rather than with models. For example
contrib.admin needs test models in order to validate that the admin
can display different types of models correctly.
contrib.admin works around the problem by putting the tests in the
Django system test suite, rather than in the contrib app itself. Based
on your description, this sounds like the same approach Django-voting
has used. This approach works fine if you're willing to maintain an
external test suite, but doesn't provide an integrated test suite that
can be easily distributed with your app.
This is one of those problems that I want to solve, but I haven't yet
given a great deal of though into how to solve. I've got a few vague
ideas banging around in my head about allowing test application and
test model definitions to be included in the test module for an
application, but those ideas aren't fully formed. Anyone that wants to
help out with some concrete suggestions (and even better - code) is
more than welcome to do so.
Russ Magee %-)
I will openly admit that I haven't given this much though, except in
the abstract. I'm certain that there are many details and gotchas that
I haven't thought of that implementation will reveal.
Broadly speaking, I'm happy with the approach you are suggesting. The
interface needs some work, though. I'd like to think that at an API
level, it could be as simple as:
apps = ['fakeapp','otherapp']
where 'fakeapp' et al are submodules of the test module that contain a
models.py definition. Obviously, the test applications need to be:
- Added to INSTALLED APPS and the app cache on startup
- Installed in the app cache before the syncdb caused by the pre-test
database flush takes effect. You shouldn't need to manually invoke
- Removed from INSTALLED_APPS and the app cache on teardown
I'm of two minds as to whether apps should define a complete
replacement for INSTALLED_APPS, or if it should be a supplement to the
INSTALLED_APPS that already exists for the project. This hits up
against the recurring issue of testing as a per-app process vs testing
as a project integration process.
The name clash problem you describe shouldn't be that big an issue -
you have the django-admin model validation tools at your disposal. You
will probably want to put in some checks to make sure that validation
only gets called once (so that you're not needlessly revalidating),
but the validator should pick out any name clashes or other conflicts.