We’re using a mix of Django’s Unit Testing, nose, and Selenium for our automated testing. This gives us a lot of power and flexibility to test all aspects of the site.
Configuration for your unit tests is mostly handled automatically. The only thing you’ll need to ensure is that the database credentials in your settings_local.py has full permissions to modify a database with test- prepended to it. For example, if my database name were zamboni this database would be test-zamboni.
If you want to run the Selenium tests you’ll need a Selenium RC server running and accepting jobs. Change the SELENIUM_CONFIG variable in settings_local.py to point to your server and the tests will run automatically. If you don’t have Selenium set up, the tests will be skipped.
To run the whole shebang use:
python manage.py test
There are a lot of options you can pass to adjust the output. Read the docs for the full set, but some common ones are:
Our continuous integration server adds some additional flags for other features (for example, coverage statistics). To see what those commands are check out the build script at scripts/build.sh.
Our test runner will try as hard as it can to skip creating a fresh database every time. If you really want to make a new database (e.g. when models have changed), set the environment variable FORCE_DB.
FORCE_DB=true python manage.py test
We support two types of automated tests right now and there are some details below but remember, if you’re confused look at existing tests for examples.
Most tests are in this category. Our test classes extend test_utils.TestCase and follow the standard rules for unit tests. We’re using JSON fixtures for the data.
Selenium tests should go under tests/selenium/ in your apps’ directory. These tests extend test_utils.SeleniumTestCase which handles all the connection steps for you and puts the selenium object in self.selenium. Full Selenium documentation is available: http://release.seleniumhq.org/selenium-core/1.0/reference.html
Tests usually fail for one of two reasons: The code has changed or the data has changed. An third reason is time. Some tests have time-dependent data usually in the fixtues. For example, some featured items have expiration dates.
We can usually save our future-selves time by setting these expirations far in the future.
If you want test that your localization works then you can add in locales in the test directory. For an example see devhub/tests/locale. These locales are not in the normal path so should not show up unless you add them to the LOCALE_PATH. If you change the .po files for these test locales, you will need to recompile the .mo files manually, for example:
msgfmt --check-format -o django.mo django.po
Frontend JavaScript is currently tested with QUnit, a simple set of functions for test setup/teardown and assertions.
You can run the tests a few different ways but during development you probably want to run them in a web browser by opening this page: http://127.0.0.1:8000/en-US/firefox/qunit/
Before you can load that page, you’ll need to adjust your settings_local.py file so it includes django-qunit:
INSTALLED_APPS += (
# ...
'django_qunit',
)
QUnit tests for the HTML page above are discovered automatically. Just add some_test.js to media/js/zamboni/tests/ and it will run in the suite. If you need to include a library file to test against, edit media/js/zamboni/tests/suite.json.
QUnit has some good examples for writing tests. Here are a few additional tips: