322 lines
11 KiB
Plaintext
322 lines
11 KiB
Plaintext
==========
|
|
Unit tests
|
|
==========
|
|
|
|
Django comes with a test suite of its own, in the ``tests`` directory of the
|
|
code base. It's our policy to make sure all tests pass at all times.
|
|
|
|
The tests cover:
|
|
|
|
* Models, the database API and everything else in core Django core (``tests/``),
|
|
* :ref:`contrib-apps` (``django/contrib/<app>/tests`` or ``tests/<app>_...``).
|
|
|
|
We appreciate any and all contributions to the test suite!
|
|
|
|
The Django tests all use the testing infrastructure that ships with Django for
|
|
testing applications. See :doc:`/topics/testing/overview` for an explanation of
|
|
how to write new tests.
|
|
|
|
.. _running-unit-tests:
|
|
|
|
Running the unit tests
|
|
----------------------
|
|
|
|
Quickstart
|
|
~~~~~~~~~~
|
|
|
|
Running the tests requires a Django settings module that defines the
|
|
databases to use. To make it easy to get started, Django provides and uses a
|
|
sample settings module that uses the SQLite database. To run the tests:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ git clone https://github.com/django/django.git django-repo
|
|
$ cd django-repo/tests
|
|
$ PYTHONPATH=..:$PYTHONPATH ./runtests.py
|
|
|
|
.. versionchanged:: 1.7
|
|
|
|
Older versions of Django required specifying a settings file:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ PYTHONPATH=..:$PYTHONPATH python ./runtests.py --settings=test_sqlite
|
|
|
|
``runtests.py`` now uses ``test_sqlite`` by default if settings aren't
|
|
provided through either ``--settings`` or :envvar:`DJANGO_SETTINGS_MODULE`.
|
|
|
|
You can avoid typing the ``PYTHONPATH`` bit each time by adding your Django
|
|
checkout to your ``PYTHONPATH`` or by installing the source checkout using pip.
|
|
See :ref:`installing-development-version`.
|
|
|
|
Having problems? See :ref:`troubleshooting-unit-tests` for some common issues.
|
|
|
|
.. _running-unit-tests-settings:
|
|
|
|
Using another ``settings`` module
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The included settings module allows you to run the test suite using
|
|
SQLite. If you want to test behavior using a different database (and
|
|
if you're proposing patches for Django, it's a good idea to test
|
|
across databases), you may need to define your own settings file.
|
|
|
|
To run the tests with different settings, ensure that the module is on your
|
|
``PYTHONPATH`` and pass the module with ``--settings``.
|
|
|
|
The :setting:`DATABASES` setting in any test settings module needs to define
|
|
two databases:
|
|
|
|
* A ``default`` database. This database should use the backend that
|
|
you want to use for primary testing
|
|
|
|
* A database with the alias ``other``. The ``other`` database is used to
|
|
establish that queries can be directed to different databases. As a result,
|
|
this database can use any backend you want. It doesn't need to use the same
|
|
backend as the ``default`` database (although it can use the same backend if
|
|
you want to). It cannot be the same database as the ``default``.
|
|
|
|
If you're using a backend that isn't SQLite, you will need to provide other
|
|
details for each database:
|
|
|
|
* The :setting:`USER` option needs to specify an existing user account
|
|
for the database. That user needs permission to execute ``CREATE DATABASE``
|
|
so that the test database can be created.
|
|
|
|
* The :setting:`PASSWORD` option needs to provide the password for
|
|
the :setting:`USER` that has been specified.
|
|
|
|
Test databases get their names by prepending ``test_`` to the value of the
|
|
:setting:`NAME` settings for the databases defined in :setting:`DATABASES`.
|
|
These test databases are deleted when the tests are finished.
|
|
|
|
.. versionchanged:: 1.7
|
|
|
|
Before Django 1.7, the :setting:`NAME` setting was mandatory and had to
|
|
be the name of an existing database to which the given user had permission
|
|
to connect.
|
|
|
|
You will also need to ensure that your database uses UTF-8 as the default
|
|
character set. If your database server doesn't use UTF-8 as a default charset,
|
|
you will need to include a value for :setting:`TEST_CHARSET` in the settings
|
|
dictionary for the applicable database.
|
|
|
|
.. _runtests-specifying-labels:
|
|
|
|
Running only some of the tests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Django's entire test suite takes a while to run, and running every single test
|
|
could be redundant if, say, you just added a test to Django that you want to
|
|
run quickly without running everything else. You can run a subset of the unit
|
|
tests by appending the names of the test modules to ``runtests.py`` on the
|
|
command line.
|
|
|
|
For example, if you'd like to run tests only for generic relations and
|
|
internationalization, type:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --settings=path.to.settings generic_relations i18n
|
|
|
|
How do you find out the names of individual tests? Look in ``tests/`` — each
|
|
directory name there is the name of a test. Contrib app names are also valid
|
|
test names.
|
|
|
|
If you just want to run a particular class of tests, you can specify a list of
|
|
paths to individual test classes. For example, to run the ``TranslationTests``
|
|
of the ``i18n`` module, type:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests
|
|
|
|
Going beyond that, you can specify an individual test method like this:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects
|
|
|
|
Running the Selenium tests
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Some admin tests require Selenium 2, Firefox and Python >= 2.6 to work via a
|
|
real Web browser. To allow those tests to run and not be skipped, you must
|
|
install the selenium_ package (version > 2.13) into your Python path and run
|
|
the tests with the ``--selenium`` option:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --settings=test_sqlite --selenium admin_inlines
|
|
|
|
|
|
.. _running-unit-tests-dependencies:
|
|
|
|
Running all the tests
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
If you want to run the full suite of tests, you'll need to install a number of
|
|
dependencies:
|
|
|
|
* bcrypt_
|
|
* docutils_
|
|
* numpy_
|
|
* Pillow_
|
|
* PyYAML_
|
|
* pytz_
|
|
* setuptools_
|
|
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
|
* gettext_ (:ref:`gettext_on_windows`)
|
|
* selenium_
|
|
* sqlparse_
|
|
|
|
You can find these dependencies in `pip requirements files`_ inside the
|
|
``tests/requirements`` directory of the Django source tree and install them
|
|
like so:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ pip install -r tests/requirements/py2.txt # Python 3: py3.txt
|
|
|
|
You can also install the database adapter(s) of your choice using
|
|
``oracle.txt``, ``mysql.txt``, or ``postgres.txt``.
|
|
|
|
If you want to test the memcached cache backend, you'll also need to define
|
|
a :setting:`CACHES` setting that points at your memcached instance.
|
|
|
|
To run the GeoDjango tests, you will need to :doc:`setup a spatial database
|
|
and install the Geospatial libraries</ref/contrib/gis/install/index>`.
|
|
|
|
Each of these dependencies is optional. If you're missing any of them, the
|
|
associated tests will be skipped.
|
|
|
|
.. _bcrypt: https://pypi.python.org/pypi/bcrypt
|
|
.. _docutils: https://pypi.python.org/pypi/docutils
|
|
.. _numpy: https://pypi.python.org/pypi/numpy
|
|
.. _Pillow: https://pypi.python.org/pypi/Pillow/
|
|
.. _PyYAML: http://pyyaml.org/wiki/PyYAML
|
|
.. _pytz: https://pypi.python.org/pypi/pytz/
|
|
.. _setuptools: https://pypi.python.org/pypi/setuptools/
|
|
.. _memcached: http://memcached.org/
|
|
.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html
|
|
.. _selenium: https://pypi.python.org/pypi/selenium
|
|
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
|
.. _pip requirements files: http://www.pip-installer.org/en/latest/user_guide.html#requirements-files
|
|
|
|
Code coverage
|
|
~~~~~~~~~~~~~
|
|
|
|
Contributors are encouraged to run coverage on the test suite to identify areas
|
|
that need additional tests. The coverage tool installation and use is described
|
|
in :ref:`testing code coverage<topics-testing-code-coverage>`.
|
|
|
|
To run coverage on the Django test suite using the standard test settings:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ coverage run ./runtests.py --settings=test_sqlite
|
|
|
|
After running coverage, generate the html report by running:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ coverage html
|
|
|
|
When running coverage for the Django tests, the included ``.coveragerc``
|
|
settings file defines ``coverage_html`` as the output directory for the report
|
|
and also excludes several directories not relevant to the results
|
|
(test code or external code included in Django).
|
|
|
|
.. _contrib-apps:
|
|
|
|
Contrib apps
|
|
------------
|
|
|
|
Tests for contrib apps go in their respective directories under
|
|
``django/contrib``, in a ``tests.py`` file. You can split the tests over
|
|
multiple modules by using a ``tests`` directory in the normal Python way.
|
|
|
|
If you have URLs that need to be mapped, put them in ``tests/urls.py``.
|
|
|
|
To run tests for just one contrib app (e.g. ``auth``), use the same
|
|
method as above:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --settings=settings django.contrib.auth
|
|
|
|
.. _troubleshooting-unit-tests:
|
|
|
|
Troubleshooting
|
|
---------------
|
|
|
|
Many test failures with ``UnicodeEncodeError``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
If the ``locales`` package is not installed, some tests will fail with a
|
|
``UnicodeEncodeError``.
|
|
|
|
You can resolve this on Debian-based systems, for example, by running:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ apt-get install locales
|
|
$ dpkg-reconfigure locales
|
|
|
|
Tests that only fail in combination
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In case a test passes when run in isolation but fails within the whole suite,
|
|
we have some tools to help analyze the problem.
|
|
|
|
The ``--bisect`` option of ``runtests.py`` will run the failing test while
|
|
halving the test set it is run together with on each iteration, often making
|
|
it possible to identify a small number of tests that may be related to the
|
|
failure.
|
|
|
|
For example, suppose that the failing test that works on its own is
|
|
``ModelTest.test_eq``, then using:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --bisect basic.tests.ModelTest.test_eq
|
|
|
|
will try to determine a test that interferes with the given one. First, the
|
|
test is run with the first half of the test suite. If a failure occurs, the
|
|
first half of the test suite is split in two groups and each group is then run
|
|
with the specified test. If there is no failure with the first half of the test
|
|
suite, the second half of the test suite is run with the specified test and
|
|
split appropriately as described earlier. The process repeats until the set of
|
|
failing tests is minimized.
|
|
|
|
The ``--pair`` option runs the given test alongside every other test from the
|
|
suite, letting you check if another test has side-effects that cause the
|
|
failure. So:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --pair basic.tests.ModelTest.test_eq
|
|
|
|
will pair ``test_eq`` with every test label.
|
|
|
|
With both ``--bisect`` and ``--pair``, if you already suspect which cases
|
|
might be responsible for the failure, you may limit tests to be cross-analyzed
|
|
by :ref:`specifying further test labels <runtests-specifying-labels>` after
|
|
the first one:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions
|
|
|
|
You can also try running any set of tests in reverse using the ``--reverse``
|
|
option in order to verify that executing tests in a different order does not
|
|
cause any trouble:
|
|
|
|
.. code-block:: bash
|
|
|
|
$ ./runtests.py basic --reverse
|
|
|
|
.. versionadded:: 1.8
|
|
|
|
The ``--reverse`` option was added.
|