Unit tests

Django自带了一个测试套件,在代码库的tests目录中。这是我们的政策,以确保所有测试在任何时候通过。

我们赞赏任何和所有的贡献的测试套件!

Django测试使用Django附带的测试基础架构来测试应用程序。有关如何编写新测试的说明,请参见Writing and running tests

Running the unit tests

Quickstart

If you are on Python < 3.3, you’ll first need to install a backport of the unittest.mock module that’s available in Python 3.3+. 有关安装mock和其他可选测试依赖关系的详细信息,请参见Running all the tests

运行测试需要一个Django设置模块来定义要使用的数据库。为了便于开始,Django提供并使用了一个使用SQLite数据库的示例设置模块。运行测试:

$ git clone https://github.com/django/django.git django-repo
$ cd django-repo/tests
$ PYTHONPATH=..:$PYTHONPATH ./runtests.py
在Django 1.7中更改:

旧版本的Django需要指定一个设置文件:

$ 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 DJANGO_SETTINGS_MODULE.

您可以通过向您的PYTHONPATH添加您的Django检出或使用pip安装源检验来避免键入PYTHONPATH位。请参阅Installing the development version

有问题吗?有关常见问题,请参阅Troubleshooting

Using another settings module

包含的设置模块允许您使用SQLite运行测试套件。如果你想使用不同的数据库测试行为(如果你正在为Django提出补丁,那么最好在数据库之间进行测试),你可能需要定义自己的设置文件。

要使用不同的设置运行测试,请确保模块位于PYTHONPATH上,并使用--settings传递模块。

任何测试设置模块中的DATABASES设置需要定义两个数据库:

  • A default数据库。此数据库应使用您要用于主测试的后端
  • 具有别名other的数据库。other数据库用于确定查询可以定向到不同的数据库。因此,此数据库可以使用您想要的任何后端。它不需要使用与default数据库相同的后端(虽然它可以使用相同的后端,如果你想)。它不能是与default相同的数据库。

如果您使用的不是SQLite的后端,则需要为每个数据库提供其他详细信息:

  • USER选项需要指定数据库的现有用户帐户。该用户需要执行CREATE DATABASE的权限,才能创建测试数据库。
  • PASSWORD选项需要为指定的USER提供密码。

测试数据库通过在DATABASES中定义的数据库的NAME设置的值之前加上test_测试完成后,将删除这些测试数据库。

在Django 1.7中更改:

在Django 1.7之前,NAME设置是必需的,并且必须是给定用户有权连接的现有数据库的名称。

您还需要确保数据库使用UTF-8作为默认字符集。如果数据库服务器未将UTF-8用作默认字符集,则需要在适用的数据库的设置字典中包含TEST_CHARSET的值。

Running only some of the tests

Django的整个测试套件需要一段时间才能运行,并且运行每一个测试可能是多余的,如果,你刚刚添加一个测试Django,你想运行快速,而不运行其他。您可以通过在命令行上将测试模块的名称附加到runtests.py来运行单元测试的子集。

例如,如果您只想对通用关系和国际化运行测试,请键入:

$ ./runtests.py --settings=path.to.settings generic_relations i18n

如何找出个别测试的名称?tests/中查看 - 每个目录名都有一个测试的名称。

如果只想运行特定类的测试,可以指定单个测试类的路径列表。例如,要运行i18n模块的TranslationTests,请键入:

$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests

除此之外,你可以指定一个单独的测试方法,如:

$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects

Running the Selenium tests

一些管理测试需要Selenium 2,Firefox和Python> = 2.6通过真正的Web浏览器工作。要允许运行并且不跳过这些测试,您必须将selenium包(版本> 2.13)安装到Python路径中,并使用--selenium选项运行测试:

$ ./runtests.py --settings=test_sqlite --selenium admin_inlines

Running all the tests

如果你想运行全套的测试,你需要安装一些依赖:

您可以在Django源代码树的tests/requirements目录中的pip需求文件中找到这些依赖关系,并安装它们,如下所示:

$ pip install -r tests/requirements/py3.txt  # Python 2: py2.txt

您还可以使用oracle.txtmysql.txtpostgres.txt安装您选择的数据库适配器。

如果要测试memcached缓存后端,还需要定义指向memcached实例的CACHES设置。

要运行GeoDjango测试,您需要setup a spatial database and install the Geospatial libraries

这些依赖关系中的每一个都是可选的。如果你缺少任何一个,相关的测试将被跳过。

Code coverage

鼓励贡献者在测试套件上运行覆盖,以识别需要额外测试的区域。覆盖工具的安装和使用在testing code coverage中进行了说明。

要使用标准测试设置在Django测试套件上运行覆盖率:

$ coverage run ./runtests.py --settings=test_sqlite

运行coverage后,通过运行以下命令生成html报告:

$ coverage html

当运行Django测试的coverage时,包含的.coveragerc设置文件将coverage_html定义为报告的输出目录,并排除与结果不相关的几个目录(测试代码或Django中包含的外部代码)。

Contrib apps

可以在tests/目录中找到contrib应用程序的测试,通常在<app_name>_tests下。例如,contrib.auth的测试位于tests/auth_tests中。

Troubleshooting

Many test failures with UnicodeEncodeError

如果未安装locales包,则某些测试将失败,并显示UnicodeEncodeError

您可以在基于Debian的系统上解决此问题,例如,运行:

$ apt-get install locales
$ dpkg-reconfigure locales

Tests that only fail in combination

如果测试通过时孤立运行,但在整个套件中失败,我们有一些工具来帮助分析问题。

runtests.py--bisect选项将运行失败的测试,同时将测试集减半,它在每次迭代中一起运行,通常可以识别一个小可能与故障相关的测试次数。

例如,假设自己工作的失败测试是ModelTest.test_eq,然后使用:

$ ./runtests.py --bisect basic.tests.ModelTest.test_eq

将尝试确定干扰给定的测试。首先,测试使用测试套件的前半部分运行。如果发生故障,则测试套件的前半部分分成两组,然后每组使用指定的测试运行。如果测试套件的前半部分没有故障,则测试套件的后半部分将按照指定的测试运行,并如前所述进行适当的拆分。该过程重复,直到该组失败测试最小化。

--pair选项运行给定的测试以及套件中的每个其他测试,让您检查另一个测试是否有导致失败的副作用。所以:

$ ./runtests.py --pair basic.tests.ModelTest.test_eq

test_eq与每个测试标签配对。

对于--bisect--pair,如果您已经怀疑哪些情况可能导致故障,您可以将测试限制为交叉分析specifying further test labels

$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions

您还可以使用--reverse选项反向运行任何一组测试,以验证以不同顺序执行测试不会导致任何故障:

$ ./runtests.py basic --reverse

如果希望检查在失败测试中运行的SQL,可以使用--debug-sql选项打开SQL logging如果将此与--verbosity=2组合,将输出所有SQL查询。

$ ./runtests.py basic --debug-sql
Django 1.8中的新功能:

添加了--reverse--debug-sql选项。