150 строки
5.4 KiB
ReStructuredText
150 строки
5.4 KiB
ReStructuredText
.. _testing:
|
|
|
|
=======
|
|
Testing
|
|
=======
|
|
|
|
We're using a mix of `Django's Unit Testing`_, :mod:`nose <nose>`, and
|
|
:mod:`Selenium <selenium>` for our automated testing. This gives us a lot of
|
|
power and flexibility to test all aspects of the site.
|
|
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
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.
|
|
|
|
|
|
Running Tests
|
|
-------------
|
|
|
|
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:
|
|
|
|
* ``--noinput`` tells Django not to ask about creating or destroying test
|
|
databases.
|
|
* ``--loggging-clear-handlers`` tells nose that you don't want to see any
|
|
logging output. Without this, our debug logging will spew all over your
|
|
console during test runs. This can be useful for debugging, but it's not that
|
|
great most of the time. See the docs for more stuff you can do with
|
|
:mod:`nose and logging <nose.plugins.logcapture>`.
|
|
* ``-a \!selenium`` tired of running selenium tests? Add this.
|
|
|
|
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 :src:`scripts/build.sh`.
|
|
|
|
|
|
Database Setup
|
|
~~~~~~~~~~~~~~
|
|
|
|
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
|
|
|
|
|
|
Writing Tests
|
|
-------------
|
|
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.
|
|
|
|
|
|
Unit/Functional Tests
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
Most tests are in this category. Our test classes extend
|
|
:class:`test_utils.TestCase` and follow the standard rules for unit tests.
|
|
We're using JSON fixtures for the data.
|
|
|
|
Selenium Tests
|
|
~~~~~~~~~~~~~~
|
|
Selenium tests should go under ``tests/selenium/`` in your apps' directory.
|
|
These tests extend :class:`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
|
|
|
|
|
|
Why Tests Fail
|
|
--------------
|
|
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.
|
|
|
|
|
|
Localization Tests
|
|
------------------
|
|
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
|
|
|
|
|
|
JavaScript Tests
|
|
----------------
|
|
|
|
Frontend JavaScript is currently tested with QUnit_, a simple set of
|
|
functions for test setup/teardown and assertions.
|
|
|
|
Running JavaScript Tests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
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:
|
|
|
|
.. code-block:: python
|
|
|
|
INSTALLED_APPS += (
|
|
# ...
|
|
'django_qunit',
|
|
)
|
|
|
|
Writing JavaScript Tests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
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:
|
|
|
|
* Any HTML required for your test should go in a sandbox using
|
|
``tests.createSandbox('#your-template')``.
|
|
See js/zamboni/tests.js for details.
|
|
* To make a useful test based on an actual production template, you can create
|
|
a snippet and include that in ``templates/qunit.html`` assigned to its own
|
|
div. During test setup, reference the div in createSandbox()
|
|
* You can use `$.mockjax`_ to test how your code handles server responses,
|
|
errors, and timeouts.
|
|
|
|
.. _`Django's Unit Testing`: http://docs.djangoproject.com/en/dev/topics/testing
|
|
.. _`Selenium RC Server`: http://seleniumhq.org/projects/remote-control/
|
|
.. _`the docs`: http://docs.djangoproject.com/en/dev/topics/testing#id1
|
|
.. _Qunit: http://docs.jquery.com/Qunit
|
|
.. _`$.mockjax`: http://enterprisejquery.com/2010/07/mock-your-ajax-requests-with-mockjax-for-rapid-development/ |