“Django/docs/2.2.x/internals/contributing/writing-code/unit-tests”的版本间差异

来自菜鸟教程
Django/docs/2.2.x/internals/contributing/writing-code/unit-tests
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:单元测试 — Django 文档}}
 
<div id="unit-tests" class="section">
 
<div id="unit-tests" class="section">
  
= Unit tests =
+
= 单元测试集 =
  
Django comes with a test suite of its own, in the <code>tests</code> directory of the
+
Django 带有自己的测试套件,位于代码库的 <code>tests</code> 目录中。 我们的政策是确保所有测试始终通过。
code base. It's our policy to make sure all tests pass at all times.
 
  
We appreciate any and all contributions to the test suite!
+
我们感谢对测试套件的所有贡献!
  
The Django tests all use the testing infrastructure that ships with Django for
+
Django 测试都使用 Django 附带的测试基础设施来测试应用程序。 有关如何编写新测试的说明,请参阅 [[../../../../topics/testing/overview|编写和运行测试]]
testing applications. See [[../../../../topics/testing/overview|<span class="doc">编写并运行测试</span>]] for an explanation of
 
how to write new tests.
 
  
 
<div id="running-the-unit-tests" class="section">
 
<div id="running-the-unit-tests" class="section">
  
 
<span id="running-unit-tests"></span>
 
<span id="running-unit-tests"></span>
== Running the unit tests ==
+
== 运行单元测试 ==
  
 
<div id="quickstart" class="section">
 
<div id="quickstart" class="section">
  
=== Quickstart ===
+
=== 快速上手 ===
  
First, [https://github.com/django/django/fork fork Django on GitHub].
+
首先, [https://github.com/django/django/fork GitHub] 上 fork Django。
  
Second, create and activate a virtual environment. If you're not familiar with
+
其次,创建并激活虚拟环境。 如果您不熟悉如何做到这一点,请阅读我们的 [[../../../../intro/contributing|贡献教程]]
how to do that, read our [[../../../../intro/contributing|<span class="doc">contributing tutorial</span>]].
 
  
Next, clone your fork, install some requirements, and run the tests:
+
接下来,克隆你的 fork,安装一些需求,然后运行测试:
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第32行: 第29行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ git clone https://github.com/YourGitHubName/django.git django-repo
+
<syntaxhighlight lang="console">$ git clone https://github.com/YourGitHubName/django.git django-repo
 
$ cd django-repo/tests
 
$ cd django-repo/tests
 
$ pip install -e ..
 
$ pip install -e ..
 
$ pip install -r requirements/py3.txt
 
$ pip install -r requirements/py3.txt
$ ./runtests.py</pre>
+
$ ./runtests.py</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Installing the requirements will likely require some operating system packages
+
安装这些要求可能需要一些您的计算机尚未安装的操作系统软件包。 您通常可以通过在 Web 上搜索错误消息的最后一行来确定要安装哪个包。 如果需要,请尝试将您的操作系统添加到搜索查询中。
that your computer doesn't have installed. You can usually figure out which
 
package to install by doing a Web search for the last line or so of the error
 
message. Try adding your operating system to the search query if needed.
 
  
If you have trouble installing the requirements, you can skip that step. See
+
如果您在安装要求时遇到问题,可以跳过该步骤。 有关安装可选测试依赖项的详细信息,请参阅 [[#running-unit-tests-dependencies|运行所有测试]] 。 如果您没有安装可选的依赖项,则需要它的测试将被跳过。
[[#running-unit-tests-dependencies|<span class="std std-ref">Running all the tests</span>]] for details on installing the optional
 
test dependencies. If you don't have an optional dependency installed, the
 
tests that require it will be skipped.
 
  
Running the tests requires a Django settings module that defines the databases
+
运行测试需要一个 Django 设置模块来定义要使用的数据库。 为了易于上手,Django 提供并使用了一个使用 SQLite 数据库的示例设置模块。 请参阅 [[#running-unit-tests-settings|使用另一个设置模块]] 以了解如何使用不同的设置模块以不同的数据库运行测试。
to use. To make it easy to get started, Django provides and uses a sample
 
settings module that uses the SQLite database. See
 
[[#running-unit-tests-settings|<span class="std std-ref">Using another settings module</span>]] to learn how to use a different settings
 
module to run the tests with a different database.
 
  
 
<div class="admonition-windows-users admonition">
 
<div class="admonition-windows-users admonition">
  
Windows users
+
Windows 用户
  
We recommend something like [https://msysgit.github.io/ Git Bash] to run
+
我们推荐使用 [https://msysgit.github.io/ Git Bash] 之类的东西来使用上述方法运行测试。
the tests using the above approach.
 
  
  
 
</div>
 
</div>
Having problems? See [[#troubleshooting-unit-tests|<span class="std std-ref">错误调试</span>]] for some common issues.
+
有问题? 有关一些常见问题,请参阅 [[#troubleshooting-unit-tests|故障排除]]
  
  
第72行: 第58行:
 
<div id="running-tests-using-tox" class="section">
 
<div id="running-tests-using-tox" class="section">
  
=== Running tests using <code>tox</code> ===
+
=== 使用 tox 运行测试 ===
  
[https://tox.readthedocs.io/ Tox] is a tool for running tests in different
+
[https://tox.readthedocs.io/ Tox] 是一个在不同的虚拟环境中运行测试的工具。 Django 包含一个基本的 <code>tox.ini</code>,它会自动执行我们的构建服务器对拉取请求执行的一些检查。 要运行单元测试和其他检查(例如 [[../coding-style#coding-style-imports|导入排序]] [[../../writing-documentation#documentation-spelling-check|文档拼写检查器]] [[../coding-style#coding-style-python|代码格式]] ),请安装并运行 [ X173X] 命令来自 Django 源代码树中的任何位置:
virtual environments. Django includes a basic <code>tox.ini</code> that automates some
 
checks that our build server performs on pull requests. To run the unit tests
 
and other checks (such as [[../coding-style#coding-style-imports|<span class="std std-ref">import sorting</span>]], the
 
[[../../writing-documentation#documentation-spelling-check|<span class="std std-ref">documentation spelling checker</span>]], and
 
[[../coding-style#coding-style-python|<span class="std std-ref">code formatting</span>]]), install and run the <code>tox</code>
 
command from any place in the Django source tree:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第86行: 第66行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ pip install tox
+
<syntaxhighlight lang="console">$ pip install tox
$ tox</pre>
+
$ tox</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
By default, <code>tox</code> runs the test suite with the bundled test settings file for
+
默认情况下,<code>tox</code> 使用 SQLite、<code>flake8</code><code>isort</code> 和文档拼写检查器的捆绑测试设置文件运行测试套件。 除了本文档中其他地方提到的系统依赖项之外,命令 <code>python3</code> 必须在您的路径上并链接到适当的 Python 版本。 可以看到默认环境列表如下:
SQLite, <code>flake8</code>, <code>isort</code>, and the documentation spelling checker. In
 
addition to the system dependencies noted elsewhere in this documentation,
 
the command <code>python3</code> must be on your path and linked to the appropriate
 
version of Python. A list of default environments can be seen as follows:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第102行: 第78行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ tox -l
+
<syntaxhighlight lang="console">$ tox -l
 
py3
 
py3
 
flake8
 
flake8
 
docs
 
docs
isort</pre>
+
isort</syntaxhighlight>
  
 
</div>
 
</div>
第113行: 第89行:
 
<div id="testing-other-python-versions-and-database-backends" class="section">
 
<div id="testing-other-python-versions-and-database-backends" class="section">
  
==== Testing other Python versions and database backends ====
+
==== 测试其他 Python 版本和数据库后端 ====
  
In addition to the default environments, <code>tox</code> supports running unit tests
+
除了默认环境,<code>tox</code> 还支持为其他版本的 Python 和其他数据库后端运行单元测试。 由于 Django 的测试套件没有为 SQLite 以外的数据库后端捆绑设置文件,但是,您必须 [[#running-unit-tests-settings|创建并提供您自己的测试设置]] 。 例如,要使用 PostgreSQL 在 Python 3.5 上运行测试:
for other versions of Python and other database backends. Since Django's test
 
suite doesn't bundle a settings file for database backends other than SQLite,
 
however, you must [[#running-unit-tests-settings|<span class="std std-ref">create and provide your own test settings</span>]]. For example, to run the tests on Python 3.5
 
using PostgreSQL:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第125行: 第97行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ tox -e py35-postgres -- --settings=my_postgres_settings</pre>
+
<syntaxhighlight lang="console">$ tox -e py35-postgres -- --settings=my_postgres_settings</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This command sets up a Python 3.5 virtual environment, installs Django's
+
此命令设置 Python 3.5 虚拟环境,安装 Django 的测试套件依赖项(包括那些用于 PostgreSQL 的依赖项),并使用提供的参数(在本例中为 <code>--settings=my_postgres_settings</code>)调用 <code>runtests.py</code>
test suite dependencies (including those for PostgreSQL), and calls
 
<code>runtests.py</code> with the supplied arguments (in this case,
 
<code>--settings=my_postgres_settings</code>).
 
  
The remainder of this documentation shows commands for running tests without
+
本文档的其余部分显示了在没有 <code>tox</code> 的情况下运行测试的命令,但是,任何传递给 <code>runtests.py</code> 的选项也可以通过在参数列表前加上 <code>--</code>,如上。
<code>tox</code>, however, any option passed to <code>runtests.py</code> can also be passed to
 
<code>tox</code> by prefixing the argument list with <code>--</code>, as above.
 
  
Tox also respects the <code>DJANGO_SETTINGS_MODULE</code> environment variable, if set.
+
Tox 还尊重 <code>DJANGO_SETTINGS_MODULE</code> 环境变量(如果已设置)。 例如,以下等效于上面的命令:
For example, the following is equivalent to the command above:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第146行: 第112行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py35-postgres</pre>
+
<syntaxhighlight lang="console">$ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py35-postgres</syntaxhighlight>
  
 
</div>
 
</div>
第155行: 第121行:
 
<div id="running-the-javascript-tests" class="section">
 
<div id="running-the-javascript-tests" class="section">
  
==== Running the JavaScript tests ====
+
==== 运行 JavaScript 测试集 ====
  
Django includes a set of [[../javascript#javascript-tests|<span class="std std-ref">JavaScript unit tests</span>]] for
+
Django 包含一组 [[../javascript#javascript-tests|JavaScript 单元测试]] ,用于某些 contrib 应用程序中的函数。 默认情况下,JavaScript 测试不使用 <code>tox</code> 运行,因为它们需要安装 Node.js,并且对于大多数补丁来说不是必需的。 要使用 <code>tox</code> 运行 JavaScript 测试:
functions in certain contrib apps. The JavaScript tests aren't run by default
 
using <code>tox</code> because they require Node.js to be installed and aren't
 
necessary for the majority of patches. To run the JavaScript tests using
 
<code>tox</code>:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第167行: 第129行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ tox -e javascript</pre>
+
<syntaxhighlight lang="console">$ tox -e javascript</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
This command runs <code>npm install</code> to ensure test requirements are up to
+
此命令运行 <code>npm install</code> 以确保测试要求是最新的,然后运行 <code>npm test</code>
date and then runs <code>npm test</code>.
 
  
  
第181行: 第142行:
 
<div id="running-tests-using-django-docker-box" class="section">
 
<div id="running-tests-using-django-docker-box" class="section">
  
=== Running tests using <code>django-docker-box</code> ===
+
=== 使用 django-docker-box 运行测试 ===
  
[https://github.com/django/django-docker-box django-docker-box] allows you to run the Django's test suite across all
+
[https://github.com/django/django-docker-box django-docker-box] 允许你在所有支持的数据库和 python 版本中运行 Django 的测试套件。 安装和使用说明见[https://github.com/django/django-docker-box django-docker-box]项目页面。
supported databases and python versions. See the [https://github.com/django/django-docker-box django-docker-box] project
 
page for installation and usage instructions.
 
  
  
第192行: 第151行:
  
 
<span id="running-unit-tests-settings"></span>
 
<span id="running-unit-tests-settings"></span>
=== Using another <code>settings</code> module ===
+
=== 使用另一个 settings 模块 ===
  
The included settings module (<code>tests/test_sqlite.py</code>) allows you to run the
+
包含的设置模块 (<code>tests/test_sqlite.py</code>) 允许您使用 SQLite 运行测试套件。 如果要使用不同的数据库运行测试,则需要定义自己的设置文件。 某些测试,例如针对 <code>contrib.postgres</code> 的测试,特定于特定的数据库后端,如果使用不同的后端运行,则会被跳过。
test suite using SQLite. If you want to run the tests using a different
 
database, you'll need to define your own settings file. Some tests, such as
 
those for <code>contrib.postgres</code>, are specific to a particular database backend
 
and will be skipped if run with a different backend.
 
  
To run the tests with different settings, ensure that the module is on your
+
要使用不同的设置运行测试,请确保模块在您的 <code>PYTHONPATH</code> 上并通过 <code>--settings</code> 的模块。
<code>PYTHONPATH</code> and pass the module with <code>--settings</code>.
 
  
The [[../../../../ref/settings#std-setting-DATABASES|<code>DATABASES</code>]] setting in any test settings module needs to define
+
任何测试设置模块中的 [[#id1|:setting:`DATABASES`]] 设置都需要定义两个数据库:
two databases:
 
  
* A <code>default</code> database. This database should use the backend that you want to use for primary testing.
+
* <code>default</code> 数据库。 此数据库应使用您要用于主要测试的后端。
* A database with the alias <code>other</code>. The <code>other</code> database is used to test that queries can be directed to different databases. This database should use the same backend as the <code>default</code>, and it must have a different name.
+
* 别名为 <code>other</code> 的数据库。 <code>other</code> 数据库用于测试查询是否可以定向到不同的数据库。 此数据库应使用与 <code>default</code> 相同的后端,并且必须具有不同的名称。
  
If you're using a backend that isn't SQLite, you will need to provide other
+
如果您使用的后端不是 SQLite,则需要为每个数据库提供其他详细信息:
details for each database:
 
  
* The [[../../../../ref/settings#std-setting-USER|<code>USER</code>]] option needs to specify an existing user account for the database. That user needs permission to execute <code>CREATE DATABASE</code> so that the test database can be created.
+
* [[#id3|:setting:`USER`]] 选项需要为数据库指定一个现有的用户帐户。 该用户需要执行 <code>CREATE DATABASE</code> 的权限,以便可以创建测试数据库。
* The [[../../../../ref/settings#std-setting-PASSWORD|<code>PASSWORD</code>]] option needs to provide the password for the [[../../../../ref/settings#std-setting-USER|<code>USER</code>]] that has been specified.
+
* [[#id5|:setting:`PASSWORD`]] 选项需要提供已经指定的 [[#id7|:setting:`USER`]] 的密码。
  
Test databases get their names by prepending <code>test_</code> to the value of the
+
测试数据库通过在 [[#id11|:setting:`DATABASES`]] 中定义的数据库的 [[#id9|:setting:`NAME`]] 设置的值前面加上 <code>test_</code> 来获取它们的名称。 测试完成后,这些测试数据库将被删除。
[[../../../../ref/settings#std-setting-NAME|<code>NAME</code>]] settings for the databases defined in [[../../../../ref/settings#std-setting-DATABASES|<code>DATABASES</code>]].
 
These test databases are deleted when the tests are finished.
 
  
You will also need to ensure that your database uses UTF-8 as the default
+
您还需要确保您的数据库使用 UTF-8 作为默认字符集。 如果您的数据库服务器不使用 UTF-8 作为默认字符集,您将需要包含一个值 [[#id13|:设置:`字符集 `]] 在适用数据库的测试设置字典中。
character set. If your database server doesn't use UTF-8 as a default charset,
 
you will need to include a value for [[../../../../ref/settings#std-setting-TEST_CHARSET|<code>CHARSET</code>]] in the
 
test settings dictionary for the applicable database.
 
  
  
第229行: 第176行:
  
 
<span id="runtests-specifying-labels"></span>
 
<span id="runtests-specifying-labels"></span>
=== Running only some of the tests ===
+
=== 执行一部分测试 ===
  
Django's entire test suite takes a while to run, and running every single test
+
Django 的整个测试套件需要一段时间才能运行,并且如果您只是向 Django 添加了一个想要快速运行而不运行其他所有测试的测试,那么运行每一个测试都可能是多余的。 您可以通过将测试模块的名称附加到命令行上的 <code>runtests.py</code> 来运行单元测试的子集。
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 <code>runtests.py</code> on the
 
command line.
 
  
For example, if you'd like to run tests only for generic relations and
+
例如,如果您只想为通用关系和国际化运行测试,请键入:
internationalization, type:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第244行: 第186行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --settings=path.to.settings generic_relations i18n</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --settings=path.to.settings generic_relations i18n</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
How do you find out the names of individual tests? Look in <code>tests/</code> — each
+
您如何找出各个测试的名称? 查看 <code>tests/</code> — 每个目录名称都有一个测试名称。
directory name there is the name of a test.
 
  
If you just want to run a particular class of tests, you can specify a list of
+
如果您只想运行特定类别的测试,您可以指定单个测试类的路径列表。 例如,要运行 <code>i18n</code> 模块的 <code>TranslationTests</code>,请键入:
paths to individual test classes. For example, to run the <code>TranslationTests</code>
 
of the <code>i18n</code> module, type:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第260行: 第199行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Going beyond that, you can specify an individual test method like this:
+
除此之外,您可以指定一个单独的测试方法,如下所示:
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第271行: 第210行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --settings=path.to.settings i18n.tests.TranslationTests.test_lazy_objects</syntaxhighlight>
  
 
</div>
 
</div>
第280行: 第219行:
 
<div id="running-the-selenium-tests" class="section">
 
<div id="running-the-selenium-tests" class="section">
  
=== Running the Selenium tests ===
+
=== 运行 Selenium 测试 ===
  
Some tests require Selenium and a Web browser. To run these tests, you must
+
某些测试需要 Selenium Web 浏览器。 要运行这些测试,您必须安装 [https://pypi.org/project/selenium/ selenium] 包并使用 <code>--selenium=&lt;BROWSERS&gt;</code> 选项运行测试。 例如,如果您安装了 Firefox Google Chrome:
install the [https://pypi.org/project/selenium/ selenium] package and run the tests with the
 
<code>--selenium=&lt;BROWSERS&gt;</code> option. For example, if you have Firefox and Google
 
Chrome installed:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第291行: 第227行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --selenium=firefox,chrome</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --selenium=firefox,chrome</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
See the [https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver selenium.webdriver] package for the list of available browsers.
+
有关可用浏览器的列表,请参阅 [https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver selenium.webdriver] 包。
  
Specifying <code>--selenium</code> automatically sets <code>--tags=selenium</code> to run only
+
指定 <code>--selenium</code> 会自动设置 <code>--tags=selenium</code> 以仅运行需要硒的测试。
the tests that require selenium.
 
  
  
第306行: 第241行:
  
 
<span id="running-unit-tests-dependencies"></span>
 
<span id="running-unit-tests-dependencies"></span>
=== Running all the tests ===
+
=== 运行所有测试 ===
  
If you want to run the full suite of tests, you'll need to install a number of
+
如果要运行完整的测试套件,则需要安装许多依赖项:
dependencies:
 
  
 
* [https://pypi.org/project/argon2_cffi/ argon2-cffi] 16.1.0+
 
* [https://pypi.org/project/argon2_cffi/ argon2-cffi] 16.1.0+
* [https://pypi.org/project/bcrypt/ bcrypt]
+
* [https://pypi.org/project/bcrypt/ 加密]
* [https://pypi.org/project/docutils/ docutils]
+
* [https://pypi.org/project/docutils/ 文档工具]
* [https://pypi.org/project/geoip2/ geoip2]
+
* [https://pypi.org/project/geoip2/ 地理IP2]
 
* [https://pypi.org/project/jinja2/ jinja2] 2.7+
 
* [https://pypi.org/project/jinja2/ jinja2] 2.7+
* [https://pypi.org/project/numpy/ numpy]
+
* [https://pypi.org/project/numpy/ 麻木的]
* [https://pypi.org/project/Pillow/ Pillow] 4.2.0+
+
* [https://pypi.org/project/Pillow/ 枕头] 4.2.0+
* [https://pyyaml.org/wiki/PyYAML PyYAML]
+
* [https://pyyaml.org/wiki/PyYAML pyyaml]
* [https://pypi.org/project/pytz/ pytz] (required)
+
* [https://pypi.org/project/pytz/ pytz](必填)
* [https://pypi.org/project/pywatchman/ pywatchman]
+
* [https://pypi.org/project/pywatchman/ 守望者]
* [https://pypi.org/project/setuptools/ setuptools]
+
* [https://pypi.org/project/setuptools/ 设置工具]
* [https://memcached.org/ memcached], plus a [[../../../../topics/cache#memcached|<span class="std std-ref">supported Python binding</span>]]
+
* [https://memcached.org/ memcached],加上一个[[../../../../topics/cache#memcached|支持的Python绑定]]
* [https://www.gnu.org/software/gettext/manual/gettext.html gettext] ([[../../../../topics/i18n/translation#gettext-on-windows|<span class="std std-ref">gettext on Windows</span>]])
+
* [https://www.gnu.org/software/gettext/manual/gettext.html gettext](Windows 上的 [[../../../../topics/i18n/translation#gettext-on-windows|gettext]]
* [https://pypi.org/project/selenium/ selenium]
+
* [https://pypi.org/project/selenium/ ]
* [https://pypi.org/project/sqlparse/ sqlparse] 0.2.2+ (required)
+
* [https://pypi.org/project/sqlparse/ sqlparse] 0.2.2+(必需)
 
* [https://pypi.org/project/tblib/ tblib] 1.5.0+
 
* [https://pypi.org/project/tblib/ tblib] 1.5.0+
  
You can find these dependencies in [https://pip.pypa.io/en/latest/user_guide/#requirements-files pip requirements files] inside the
+
您可以在 Django 源代码树的 <code>tests/requirements</code> 目录中的 [https://pip.pypa.io/en/latest/user_guide/#requirements-files pip 需求文件] 中找到这些依赖项,并像这样安装它们:
<code>tests/requirements</code> directory of the Django source tree and install them
 
like so:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第336行: 第268行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ pip install -r tests/requirements/py3.txt</pre>
+
<syntaxhighlight lang="console">$ pip install -r tests/requirements/py3.txt</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
如果你在安装过程中发生了错误,可能是你的系统缺少一个或多个Python依赖包。请参考安装失败的包的文档或者在网上搜索错误的提示信息。
+
如果您在安装过程中遇到错误,您的系统可能缺少一个或多个 Python 包的依赖项。 查阅失败包的文档或使用您遇到的错误消息在 Web 上搜索。
  
You can also install the database adapter(s) of your choice using
+
您还可以使用 <code>oracle.txt</code><code>mysql.txt</code> <code>postgres.txt</code> 安装您选择的数据库适配器。
<code>oracle.txt</code>, <code>mysql.txt</code>, or <code>postgres.txt</code>.
 
  
If you want to test the memcached cache backend, you'll also need to define
+
如果你想测试 memcached 缓存后端,你还需要定义一个指向你的 memcached 实例的 [[#id15|:setting:`CACHES`]] 设置。
a [[../../../../ref/settings#std-setting-CACHES|<code>CACHES</code>]] setting that points at your memcached instance.
 
  
To run the GeoDjango tests, you will need to [[../../../../ref/contrib/gis/install/index|<span class="doc">setup a spatial database
+
要运行 GeoDjango 测试,您需要 [[../../../../ref/contrib/gis/install/index|设置空间数据库并安装地理空间库]]
and install the Geospatial libraries</span>]].
 
  
Each of these dependencies is optional. If you're missing any of them, the
+
这些依赖项中的每一个都是可选的。 如果您遗漏了其中任何一个,相关的测试将被跳过。
associated tests will be skipped.
 
  
To run some of the autoreload tests, you'll need to install the [https://facebook.github.io/watchman/ Watchman]
+
要运行一些自动重载测试,您需要安装 [https://facebook.github.io/watchman/ Watchman] 服务。
service.
 
  
  
第362行: 第289行:
 
<div id="code-coverage" class="section">
 
<div id="code-coverage" class="section">
  
=== Code coverage ===
+
=== 代码覆盖率 ===
  
Contributors are encouraged to run coverage on the test suite to identify areas
+
鼓励贡献者在测试套件上运行覆盖以识别需要额外测试的区域。 覆盖率工具的安装和使用在[[../../../../topics/testing/advanced#topics-testing-code-coverage|测试代码覆盖率]]中有描述。
that need additional tests. The coverage tool installation and use is described
 
in [[../../../../topics/testing/advanced#topics-testing-code-coverage|<span class="std std-ref">testing code coverage</span>]].
 
  
Coverage should be run in a single process to obtain accurate statistics. To
+
覆盖率应该在单个过程中运行以获得准确的统计数据。 要使用标准测试设置在 Django 测试套件上运行覆盖率:
run coverage on the Django test suite using the standard test settings:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第375行: 第299行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ coverage run ./runtests.py --settings=test_sqlite --parallel=1</pre>
+
<syntaxhighlight lang="console">$ coverage run ./runtests.py --settings=test_sqlite --parallel=1</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
After running coverage, generate the html report by running:
+
运行coverage后,通过运行生成html报告:
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第386行: 第310行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ coverage html</pre>
+
<syntaxhighlight lang="console">$ coverage html</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
When running coverage for the Django tests, the included <code>.coveragerc</code>
+
在运行 Django 测试的覆盖率时,包含的 <code>.coveragerc</code> 设置文件将 <code>coverage_html</code> 定义为报告的输出目录,并且还排除了几个与结果无关的目录(测试代码或外部代码包含在姜戈)。
settings file defines <code>coverage_html</code> 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).
 
  
  
第402行: 第323行:
 
<div id="contrib-apps" class="section">
 
<div id="contrib-apps" class="section">
  
<span id="id1"></span>
+
<span id="id17"></span>
== Contrib apps ==
+
== Contrib 应用程序 ==
  
Tests for contrib apps can be found in the <code>tests/</code> directory, typically
+
可以在 <code>tests/</code> 目录中找到对 contrib 应用程序的测试,通常在 <code>&lt;app_name&gt;_tests</code> 下。 例如,<code>contrib.auth</code> 的测试位于 <code>tests/auth_tests</code>
under <code>&lt;app_name&gt;_tests</code>. For example, tests for <code>contrib.auth</code> are located
 
in <code>tests/auth_tests</code>.
 
  
  
第418行: 第337行:
 
<div id="test-suite-hangs-or-shows-failures-on-master-branch" class="section">
 
<div id="test-suite-hangs-or-shows-failures-on-master-branch" class="section">
  
=== Test suite hangs or shows failures on <code>master</code> branch ===
+
=== 测试套件在 master 分支上挂起或显示失败 ===
  
Ensure you have the latest point release of a [[../../../../faq/install#faq-python-version-support|<span class="std std-ref">supported Python version</span>]], since there are often bugs in earlier versions
+
确保您拥有 [[../../../../faq/install#faq-python-version-support|支持的 Python 版本]] 的最新版本,因为早期版本中经常存在可能导致测试套件失败或挂起的错误。
that may cause the test suite to fail or hang.
 
  
On '''macOS''' (High Sierra and newer versions), you might see this message
+
'''macOS'''(High Sierra 和更新版本)上,您可能会看到此消息被记录,之后测试挂起:
logged, after which the tests hang:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第430行: 第347行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>objc[42074]: +[__NSPlaceholderDate initialize] may have been in progress in
+
<syntaxhighlight lang="console">objc[42074]: +[__NSPlaceholderDate initialize] may have been in progress in
another thread when fork() was called.</pre>
+
another thread when fork() was called.</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
To avoid this set a <code>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</code> environment
+
为了避免这种情况,请设置 <code>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</code> 环境变量,例如:
variable, for example:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第443行: 第359行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py</pre>
+
<syntaxhighlight lang="console">$ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Or add <code>export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES</code> to your shell's
+
或者将 <code>export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES</code> 添加到您的 shell 的启动文件中(例如 <code>~/.profile</code>)。
startup file (e.g. <code>~/.profile</code>).
 
  
  
第455行: 第370行:
 
<div id="many-test-failures-with-unicodeencodeerror" class="section">
 
<div id="many-test-failures-with-unicodeencodeerror" class="section">
  
=== Many test failures with <code>UnicodeEncodeError</code> ===
+
=== UnicodeEncodeError 的许多测试失败 ===
  
If the <code>locales</code> package is not installed, some tests will fail with a
+
如果未安装 <code>locales</code> 软件包,某些测试将失败并显示 <code>UnicodeEncodeError</code>
<code>UnicodeEncodeError</code>.
 
  
You can resolve this on Debian-based systems, for example, by running:
+
您可以在基于 Debian 的系统上解决此问题,例如,通过运行:
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第466行: 第380行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ apt-get install locales
+
<syntaxhighlight lang="console">$ apt-get install locales
$ dpkg-reconfigure locales</pre>
+
$ dpkg-reconfigure locales</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can resolve this for macOS systems by configuring your shell's locale:
+
您可以通过配置 shell 的语言环境为 macOS 系统解决此问题:
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第478行: 第392行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ export LANG=&quot;en_US.UTF-8&quot;
+
<syntaxhighlight lang="console">$ export LANG="en_US.UTF-8"
$ export LC_ALL=&quot;en_US.UTF-8&quot;</pre>
+
$ export LC_ALL="en_US.UTF-8"</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Run the <code>locale</code> command to confirm the change. Optionally, add those export
+
运行 <code>locale</code> 命令以确认更改。 或者,将这些导出命令添加到您的 shell 的启动文件中(例如 <code>~/.bashrc</code> for Bash) 以避免必须重新输入它们。
commands to your shell's startup file (e.g. <code>~/.bashrc</code> for Bash) to avoid
 
having to retype them.
 
  
  
第492行: 第404行:
 
<div id="tests-that-only-fail-in-combination" class="section">
 
<div id="tests-that-only-fail-in-combination" class="section">
  
=== 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 <code>--bisect</code> option of <code>runtests.py</code> will run the failing test while
+
<code>runtests.py</code> <code>--bisect</code> 选项将运行失败的测试,同时在每次迭代中将与它一起运行的测试集减半,通常可以识别出可能与此相关的少量测试失败。
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
+
例如,假设单独运行的失败测试是 <code>ModelTest.test_eq</code>,然后使用:
<code>ModelTest.test_eq</code>, then using:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第509行: 第416行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --bisect basic.tests.ModelTest.test_eq</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --bisect basic.tests.ModelTest.test_eq</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
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 <code>--pair</code> option runs the given test alongside every other test from the
+
<code>--pair</code> 选项与套件中的所有其他测试一起运行给定的测试,让您检查另一个测试是否有导致失败的副作用。 所以:
suite, letting you check if another test has side-effects that cause the
 
failure. So:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第530行: 第429行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --pair basic.tests.ModelTest.test_eq</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --pair basic.tests.ModelTest.test_eq</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
will pair <code>test_eq</code> with every test label.
+
<code>test_eq</code> 与每个测试标签配对。
  
With both <code>--bisect</code> and <code>--pair</code>, if you already suspect which cases
+
对于 <code>--bisect</code> <code>--pair</code>,如果您已经怀疑哪些情况可能是导致失败的原因,您可以将测试限制为由 [[#runtests-specifying-labels|指定进一步的测试标签]] 之后进行交叉分析第一个:
might be responsible for the failure, you may limit tests to be cross-analyzed
 
by [[#runtests-specifying-labels|<span class="std std-ref">specifying further test labels</span>]] after
 
the first one:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第546行: 第442行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py --pair basic.tests.ModelTest.test_eq queries transactions</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also try running any set of tests in reverse using the <code>--reverse</code>
+
您还可以尝试使用 <code>--reverse</code> 选项反向运行任何一组测试,以验证以不同顺序执行测试不会导致任何问题:
option in order to verify that executing tests in a different order does not
 
cause any trouble:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第559行: 第453行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py basic --reverse</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py basic --reverse</syntaxhighlight>
  
 
</div>
 
</div>
第568行: 第462行:
 
<div id="seeing-the-sql-queries-run-during-a-test" class="section">
 
<div id="seeing-the-sql-queries-run-during-a-test" class="section">
  
=== Seeing the SQL queries run during a test ===
+
=== 查看测试期间运行的 SQL 查询 ===
  
If you wish to examine the SQL being run in failing tests, you can turn on
+
如果您希望检查在失败测试中运行的 SQL,您可以使用 <code>--debug-sql</code> 选项打开 [[../../../../topics/logging#django-db-logger|SQL 日志记录]] 。 如果将其与 <code>--verbosity=2</code> 结合使用,将输出所有 SQL 查询:
[[../../../../topics/logging#django-db-logger|<span class="std std-ref">SQL logging</span>]] using the <code>--debug-sql</code> option. If you
 
combine this with <code>--verbosity=2</code>, all SQL queries will be output:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第578行: 第470行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py basic --debug-sql</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py basic --debug-sql</syntaxhighlight>
  
 
</div>
 
</div>
第587行: 第479行:
 
<div id="seeing-the-full-traceback-of-a-test-failure" class="section">
 
<div id="seeing-the-full-traceback-of-a-test-failure" class="section">
  
=== Seeing the full traceback of a test failure ===
+
=== 查看测试失败的完整追溯 ===
  
By default tests are run in parallel with one process per core. When the tests
+
默认情况下,测试与每个内核一个进程并行运行。 但是,当测试并行运行时,您只会看到任何测试失败的截断回溯。 您可以使用 <code>--parallel</code> 选项调整此行为:
are run in parallel, however, you'll only see a truncated traceback for any
 
test failures. You can adjust this behavior with the <code>--parallel</code> option:
 
  
 
<div class="highlight-console notranslate">
 
<div class="highlight-console notranslate">
第597行: 第487行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>$ ./runtests.py basic --parallel=1</pre>
+
<syntaxhighlight lang="console">$ ./runtests.py basic --parallel=1</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
You can also use the <code>DJANGO_TEST_PROCESSES</code> environment variable for this
+
为此,您还可以使用 <code>DJANGO_TEST_PROCESSES</code> 环境变量。
purpose.
 
  
  
第611行: 第500行:
 
<div id="tips-for-writing-tests" class="section">
 
<div id="tips-for-writing-tests" class="section">
  
== Tips for writing tests ==
+
== 编写测试的技巧 ==
  
 
<div id="isolating-model-registration" class="section">
 
<div id="isolating-model-registration" class="section">
  
=== Isolating model registration ===
+
=== 隔离模型注册 ===
  
To avoid polluting the global [[../../../../ref/applications#django.apps|<code>apps</code>]] registry and prevent
+
为避免污染全局 [[../../../../ref/applications#django.apps|apps]] 注册表并防止不必要的表创建,测试方法中定义的模型应绑定到临时 <code>Apps</code> 实例:
unnecessary table creation, models defined in a test method should be bound to
 
a temporary <code>Apps</code> instance:
 
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第625行: 第512行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.apps.registry import Apps
+
<syntaxhighlight lang="python">from django.apps.registry import Apps
 
from django.db import models
 
from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
第636行: 第523行:
 
             class Meta:
 
             class Meta:
 
                 apps = test_apps
 
                 apps = test_apps
         ...</pre>
+
         ...</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
; <code>django.test.utils.</code><code>isolate_apps</code><span class="sig-paren">(</span>''<span class="o">*</span><span class="n">app_labels</span>'', ''<span class="n">attr_name</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">kwarg_name</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">django.test.utils.</span></span><span class="sig-name descname"><span class="pre">isolate_apps</span></span><span class="sig-paren">(</span>''<span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">app_labels</span></span>'', ''<span class="n"><span class="pre">attr_name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">kwarg_name</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span>
 
:  
 
:  
  
Since this pattern involves a lot of boilerplate, Django provides the
+
由于此模式涉及大量样板文件,Django 提供了 [[#django.test.utils.isolate_apps|isolate_apps()]] 装饰器。 它是这样使用的:
[[#django.test.utils.isolate_apps|<code>isolate_apps()</code>]] decorator. It's used like this:
 
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第651行: 第537行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
 
from django.test.utils import isolate_apps
 
from django.test.utils import isolate_apps
第660行: 第546行:
 
         class TestModel(models.Model):
 
         class TestModel(models.Model):
 
             pass
 
             pass
         ...</pre>
+
         ...</syntaxhighlight>
  
 
</div>
 
</div>
第667行: 第553行:
 
<div class="admonition-setting-app-label admonition">
 
<div class="admonition-setting-app-label admonition">
  
Setting <code>app_label</code>
+
设置 <code>app_label</code>
  
Models defined in a test method with no explicit
+
在没有显式 [[../../../../ref/models/options#django.db.models.Options|app_label]] 的测试方法中定义的模型会自动分配其测试类所在的应用程序的标签。
[[../../../../ref/models/options#django.db.models.Options|<code>app_label</code>]] are automatically assigned the
 
label of the app in which their test class is located.
 
  
In order to make sure the models defined within the context of
+
为了确保在 [[#django.test.utils.isolate_apps|isolate_apps()]] 实例的上下文中定义的模型正确安装,您应该将一组目标 <code>app_label</code> 作为参数传递:
[[#django.test.utils.isolate_apps|<code>isolate_apps()</code>]] instances are correctly
 
installed, you should pass the set of targeted <code>app_label</code> as arguments:
 
  
<div id="id2" class="literal-block-wrapper docutils container">
+
<div id="id18" class="literal-block-wrapper docutils container">
  
 
<div class="code-block-caption">
 
<div class="code-block-caption">
  
<span class="caption-text">tests/app_label/tests.py</span>
+
<span class="caption-text">测试/app_label/tests.py</span>
  
 
</div>
 
</div>
第688行: 第570行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
 
from django.test.utils import isolate_apps
 
from django.test.utils import isolate_apps
第702行: 第584行:
 
             class Meta:
 
             class Meta:
 
                 app_label = 'other_app_label'
 
                 app_label = 'other_app_label'
         ...</pre>
+
         ...</syntaxhighlight>
  
 
</div>
 
</div>
第711行: 第593行:
  
 
</div>
 
</div>
The decorator can also be applied to classes:
+
装饰器也可以应用于类:
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第717行: 第599行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
 
from django.test.utils import isolate_apps
 
from django.test.utils import isolate_apps
第726行: 第608行:
 
         class TestModel(models.Model):
 
         class TestModel(models.Model):
 
             pass
 
             pass
         ...</pre>
+
         ...</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
The temporary <code>Apps</code> instance used to isolate model registration can be
+
当用作类装饰器时,可以使用 <code>attr_name</code> 参数将用于隔离模型注册的临时 <code>Apps</code> 实例作为属性检索:
retrieved as an attribute when used as a class decorator by using the
 
<code>attr_name</code> parameter:
 
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第739行: 第619行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
 
from django.test.utils import isolate_apps
 
from django.test.utils import isolate_apps
第748行: 第628行:
 
         class TestModel(models.Model):
 
         class TestModel(models.Model):
 
             pass
 
             pass
         self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)</pre>
+
         self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Or as an argument on the test method when used as a method decorator by using
+
或者作为测试方法的参数,当用作方法装饰器时,使用 <code>kwarg_name</code> 参数:
the <code>kwarg_name</code> parameter:
 
  
 
<div class="highlight-python notranslate">
 
<div class="highlight-python notranslate">
第760行: 第639行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>from django.db import models
+
<syntaxhighlight lang="python">from django.db import models
 
from django.test import SimpleTestCase
 
from django.test import SimpleTestCase
 
from django.test.utils import isolate_apps
 
from django.test.utils import isolate_apps
第769行: 第648行:
 
         class TestModel(models.Model):
 
         class TestModel(models.Model):
 
             pass
 
             pass
         self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)</pre>
+
         self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)</syntaxhighlight>
  
 
</div>
 
</div>
第780行: 第659行:
  
 
</div>
 
</div>
 +
<div class="clearer">
  
[[Category:Django 2.2.x 中文文档]]
+
 
 +
 
 +
</div>
 +
 
 +
[[Category:Django 2.2.x 文档]]

2021年10月31日 (日) 04:04的最新版本

单元测试集

Django 带有自己的测试套件,位于代码库的 tests 目录中。 我们的政策是确保所有测试始终通过。

我们感谢对测试套件的所有贡献!

Django 测试都使用 Django 附带的测试基础设施来测试应用程序。 有关如何编写新测试的说明,请参阅 编写和运行测试

运行单元测试

快速上手

首先, 在 GitHub 上 fork Django。

其次,创建并激活虚拟环境。 如果您不熟悉如何做到这一点,请阅读我们的 贡献教程

接下来,克隆你的 fork,安装一些需求,然后运行测试:

$ git clone https://github.com/YourGitHubName/django.git django-repo
$ cd django-repo/tests
$ pip install -e ..
$ pip install -r requirements/py3.txt
$ ./runtests.py

安装这些要求可能需要一些您的计算机尚未安装的操作系统软件包。 您通常可以通过在 Web 上搜索错误消息的最后一行来确定要安装哪个包。 如果需要,请尝试将您的操作系统添加到搜索查询中。

如果您在安装要求时遇到问题,可以跳过该步骤。 有关安装可选测试依赖项的详细信息,请参阅 运行所有测试 。 如果您没有安装可选的依赖项,则需要它的测试将被跳过。

运行测试需要一个 Django 设置模块来定义要使用的数据库。 为了易于上手,Django 提供并使用了一个使用 SQLite 数据库的示例设置模块。 请参阅 使用另一个设置模块 以了解如何使用不同的设置模块以不同的数据库运行测试。

Windows 用户

我们推荐使用 Git Bash 之类的东西来使用上述方法运行测试。


有问题? 有关一些常见问题,请参阅 故障排除


使用 tox 运行测试

Tox 是一个在不同的虚拟环境中运行测试的工具。 Django 包含一个基本的 tox.ini,它会自动执行我们的构建服务器对拉取请求执行的一些检查。 要运行单元测试和其他检查(例如 导入排序文档拼写检查器代码格式 ),请安装并运行 [ X173X] 命令来自 Django 源代码树中的任何位置:

$ pip install tox
$ tox

默认情况下,tox 使用 SQLite、flake8isort 和文档拼写检查器的捆绑测试设置文件运行测试套件。 除了本文档中其他地方提到的系统依赖项之外,命令 python3 必须在您的路径上并链接到适当的 Python 版本。 可以看到默认环境列表如下:

$ tox -l
py3
flake8
docs
isort

测试其他 Python 版本和数据库后端

除了默认环境,tox 还支持为其他版本的 Python 和其他数据库后端运行单元测试。 由于 Django 的测试套件没有为 SQLite 以外的数据库后端捆绑设置文件,但是,您必须 创建并提供您自己的测试设置 。 例如,要使用 PostgreSQL 在 Python 3.5 上运行测试:

$ tox -e py35-postgres -- --settings=my_postgres_settings

此命令设置 Python 3.5 虚拟环境,安装 Django 的测试套件依赖项(包括那些用于 PostgreSQL 的依赖项),并使用提供的参数(在本例中为 --settings=my_postgres_settings)调用 runtests.py

本文档的其余部分显示了在没有 tox 的情况下运行测试的命令,但是,任何传递给 runtests.py 的选项也可以通过在参数列表前加上 --,如上。

Tox 还尊重 DJANGO_SETTINGS_MODULE 环境变量(如果已设置)。 例如,以下等效于上面的命令:

$ DJANGO_SETTINGS_MODULE=my_postgres_settings tox -e py35-postgres

运行 JavaScript 测试集

Django 包含一组 JavaScript 单元测试 ,用于某些 contrib 应用程序中的函数。 默认情况下,JavaScript 测试不使用 tox 运行,因为它们需要安装 Node.js,并且对于大多数补丁来说不是必需的。 要使用 tox 运行 JavaScript 测试:

$ tox -e javascript

此命令运行 npm install 以确保测试要求是最新的,然后运行 npm test


使用 django-docker-box 运行测试

django-docker-box 允许你在所有支持的数据库和 python 版本中运行 Django 的测试套件。 安装和使用说明见django-docker-box项目页面。


使用另一个 settings 模块

包含的设置模块 (tests/test_sqlite.py) 允许您使用 SQLite 运行测试套件。 如果要使用不同的数据库运行测试,则需要定义自己的设置文件。 某些测试,例如针对 contrib.postgres 的测试,特定于特定的数据库后端,如果使用不同的后端运行,则会被跳过。

要使用不同的设置运行测试,请确保模块在您的 PYTHONPATH 上并通过 --settings 的模块。

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

  • default 数据库。 此数据库应使用您要用于主要测试的后端。
  • 别名为 other 的数据库。 other 数据库用于测试查询是否可以定向到不同的数据库。 此数据库应使用与 default 相同的后端,并且必须具有不同的名称。

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

  • :setting:`USER` 选项需要为数据库指定一个现有的用户帐户。 该用户需要执行 CREATE DATABASE 的权限,以便可以创建测试数据库。
  • :setting:`PASSWORD` 选项需要提供已经指定的 :setting:`USER` 的密码。

测试数据库通过在 :setting:`DATABASES` 中定义的数据库的 :setting:`NAME` 设置的值前面加上 test_ 来获取它们的名称。 测试完成后,这些测试数据库将被删除。

您还需要确保您的数据库使用 UTF-8 作为默认字符集。 如果您的数据库服务器不使用 UTF-8 作为默认字符集,您将需要包含一个值 :设置:`字符集 ` 在适用数据库的测试设置字典中。


执行一部分测试

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

运行 Selenium 测试

某些测试需要 Selenium 和 Web 浏览器。 要运行这些测试,您必须安装 selenium 包并使用 --selenium=<BROWSERS> 选项运行测试。 例如,如果您安装了 Firefox 和 Google Chrome:

$ ./runtests.py --selenium=firefox,chrome

有关可用浏览器的列表,请参阅 selenium.webdriver 包。

指定 --selenium 会自动设置 --tags=selenium 以仅运行需要硒的测试。


运行所有测试

如果要运行完整的测试套件,则需要安装许多依赖项:

您可以在 Django 源代码树的 tests/requirements 目录中的 pip 需求文件 中找到这些依赖项,并像这样安装它们:

$ pip install -r tests/requirements/py3.txt

如果您在安装过程中遇到错误,您的系统可能缺少一个或多个 Python 包的依赖项。 查阅失败包的文档或使用您遇到的错误消息在 Web 上搜索。

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

如果你想测试 memcached 缓存后端,你还需要定义一个指向你的 memcached 实例的 :setting:`CACHES` 设置。

要运行 GeoDjango 测试,您需要 设置空间数据库并安装地理空间库

这些依赖项中的每一个都是可选的。 如果您遗漏了其中任何一个,相关的测试将被跳过。

要运行一些自动重载测试,您需要安装 Watchman 服务。


代码覆盖率

鼓励贡献者在测试套件上运行覆盖以识别需要额外测试的区域。 覆盖率工具的安装和使用在测试代码覆盖率中有描述。

覆盖率应该在单个过程中运行以获得准确的统计数据。 要使用标准测试设置在 Django 测试套件上运行覆盖率:

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

运行coverage后,通过运行生成html报告:

$ coverage html

在运行 Django 测试的覆盖率时,包含的 .coveragerc 设置文件将 coverage_html 定义为报告的输出目录,并且还排除了几个与结果无关的目录(测试代码或外部代码包含在姜戈)。


Contrib 应用程序

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


错误调试

测试套件在 master 分支上挂起或显示失败

确保您拥有 支持的 Python 版本 的最新版本,因为早期版本中经常存在可能导致测试套件失败或挂起的错误。

macOS(High Sierra 和更新版本)上,您可能会看到此消息被记录,之后测试挂起:

objc[42074]: +[__NSPlaceholderDate initialize] may have been in progress in
another thread when fork() was called.

为了避免这种情况,请设置 OBJC_DISABLE_INITIALIZE_FORK_SAFETY 环境变量,例如:

$ OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES ./runtests.py

或者将 export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES 添加到您的 shell 的启动文件中(例如 ~/.profile)。


UnicodeEncodeError 的许多测试失败

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

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

$ apt-get install locales
$ dpkg-reconfigure locales

您可以通过配置 shell 的语言环境为 macOS 系统解决此问题:

$ export LANG="en_US.UTF-8"
$ export LC_ALL="en_US.UTF-8"

运行 locale 命令以确认更改。 或者,将这些导出命令添加到您的 shell 的启动文件中(例如 ~/.bashrc for Bash) 以避免必须重新输入它们。


仅在组合中失败的测试

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

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,如果您已经怀疑哪些情况可能是导致失败的原因,您可以将测试限制为由 指定进一步的测试标签 之后进行交叉分析第一个:

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

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

$ ./runtests.py basic --reverse

查看测试期间运行的 SQL 查询

如果您希望检查在失败测试中运行的 SQL,您可以使用 --debug-sql 选项打开 SQL 日志记录 。 如果将其与 --verbosity=2 结合使用,将输出所有 SQL 查询:

$ ./runtests.py basic --debug-sql

查看测试失败的完整追溯

默认情况下,测试与每个内核一个进程并行运行。 但是,当测试并行运行时,您只会看到任何测试失败的截断回溯。 您可以使用 --parallel 选项调整此行为:

$ ./runtests.py basic --parallel=1

为此,您还可以使用 DJANGO_TEST_PROCESSES 环境变量。


编写测试的技巧

隔离模型注册

为避免污染全局 apps 注册表并防止不必要的表创建,测试方法中定义的模型应绑定到临时 Apps 实例:

from django.apps.registry import Apps
from django.db import models
from django.test import SimpleTestCase

class TestModelDefinition(SimpleTestCase):
    def test_model_definition(self):
        test_apps = Apps(['app_label'])

        class TestModel(models.Model):
            class Meta:
                apps = test_apps
        ...
django.test.utils.isolate_apps(*app_labels, attr_name=None, kwarg_name=None)

由于此模式涉及大量样板文件,Django 提供了 isolate_apps() 装饰器。 它是这样使用的:

from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps

class TestModelDefinition(SimpleTestCase):
    @isolate_apps('app_label')
    def test_model_definition(self):
        class TestModel(models.Model):
            pass
        ...

设置 app_label

在没有显式 app_label 的测试方法中定义的模型会自动分配其测试类所在的应用程序的标签。

为了确保在 isolate_apps() 实例的上下文中定义的模型正确安装,您应该将一组目标 app_label 作为参数传递:

测试/app_label/tests.py

from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps

class TestModelDefinition(SimpleTestCase):
    @isolate_apps('app_label', 'other_app_label')
    def test_model_definition(self):
        # This model automatically receives app_label='app_label'
        class TestModel(models.Model):
            pass

        class OtherAppModel(models.Model):
            class Meta:
                app_label = 'other_app_label'
        ...

装饰器也可以应用于类:

from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps

@isolate_apps('app_label')
class TestModelDefinition(SimpleTestCase):
    def test_model_definition(self):
        class TestModel(models.Model):
            pass
        ...

当用作类装饰器时,可以使用 attr_name 参数将用于隔离模型注册的临时 Apps 实例作为属性检索:

from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps

@isolate_apps('app_label', attr_name='apps')
class TestModelDefinition(SimpleTestCase):
    def test_model_definition(self):
        class TestModel(models.Model):
            pass
        self.assertIs(self.apps.get_model('app_label', 'TestModel'), TestModel)

或者作为测试方法的参数,当用作方法装饰器时,使用 kwarg_name 参数:

from django.db import models
from django.test import SimpleTestCase
from django.test.utils import isolate_apps

class TestModelDefinition(SimpleTestCase):
    @isolate_apps('app_label', kwarg_name='apps')
    def test_model_definition(self, apps):
        class TestModel(models.Model):
            pass
        self.assertIs(apps.get_model('app_label', 'TestModel'), TestModel)