Can I launch tests for my reusable Django app without incorporating this app into a project?
My app uses some models, so it is necessary to provide (TEST_)DATABASE_*
settings. Where should I store them and how should I launch tests?
For a Django project, I can run tests with manage.py test
; when I use django-admin.py test
with my standalone app, I get:
Error: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
What are the best practises here?
I've ended with such solution (it was inspired by solution found in django-voting):
Create file eg. 'runtests.py' in tests dir containing:
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.For Django 1.7 it's slightly different. Assuming you have the following directory structure for app
foo
:This is how the Django project itself structures its tests.
You want to run all tests in
foo/tests/
with the command:You also want to be able to run the command from a parent directory of
tests
, e.g. by Tox or Invoke, just likepython3 foo/tests/runtests.py
.The solution I present here is quite reusable, only the app's name
foo
must be adjusted (and additional apps, if necessary). They can not be installed via modify_settings, because it would miss the database setup.The following files are needed:
urls.py
runtests.py
Some of the settings are optional; they improve speed or a more realistic environment.
The second argument points to the current directory. It makes use of the feature of providing a path to a directory to discover tests below that directory.
In a pure pytest context, to provide just enough Django environment to get tests running for my reusable app without an actual Django project, I needed the following pieces:
pytest.ini:
test_settings.py:
base_urls.py:
templates/base.html:
If any of your tests hit actual views, your app's templates will probably be extending the project
base.html
, so that file must exist. In my case, I just created an empty filetemplates/base.html
.I can now run
pytest -x -v
from my standalone reusable app directory, without a Django project.The correct usage of Django (>= 1.4) test runner is as follows:
DjangoTestSuiteRunner and DiscoverRunner have mostly compatible interfaces.
For more information you should consult the "Defining a Test Runner" docs:
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 ofexample_project
.When i want to install all dependencies used by my project and run tests, i only need to do following:
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