mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
307 lines
170 KiB
HTML
307 lines
170 KiB
HTML
<div class="body" role="main"><div class="section" id="module-doctest"><h1><span class="yiyi-st" id="yiyi-10">26.3. <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> - 测试交互式Python示例</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/doctest.py">Lib / doctest.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>模块搜索看起来像交互式Python会话的文本片段,然后执行这些会话以验证它们完全按照所示方式工作。</span><span class="yiyi-st" id="yiyi-13">有几种常用的方法可以使用doctest:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-14">通过验证所有交互式示例仍按记录工作来检查模块的文档是否是最新的。</span></li><li><span class="yiyi-st" id="yiyi-15">通过验证测试文件或测试对象中的交互式示例如预期工作来执行回归测试。</span></li><li><span class="yiyi-st" id="yiyi-16">为包编写教程文档,用输入输出示例大量地说明。</span><span class="yiyi-st" id="yiyi-17">根据实例或说明文本是否被强调,这具有“识字测试”或“可执行文档”的味道。</span></li></ul><p><span class="yiyi-st" id="yiyi-18">首先来看一个完整但简单的示例模块:</span></p><pre><code class="language-python"><span></span><span class="sd">"""</span>
|
||
<span class="sd">This is the "example" module.</span>
|
||
|
||
<span class="sd">The example module supplies one function, factorial(). For example,</span>
|
||
|
||
<span class="sd">>>> factorial(5)</span>
|
||
<span class="sd">120</span>
|
||
<span class="sd">"""</span>
|
||
|
||
<span class="k">def</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||
<span class="sd">"""Return the factorial of n, an exact integer >= 0.</span>
|
||
|
||
<span class="sd"> >>> [factorial(n) for n in range(6)]</span>
|
||
<span class="sd"> [1, 1, 2, 6, 24, 120]</span>
|
||
<span class="sd"> >>> factorial(30)</span>
|
||
<span class="sd"> 265252859812191058636308480000000</span>
|
||
<span class="sd"> >>> factorial(-1)</span>
|
||
<span class="sd"> Traceback (most recent call last):</span>
|
||
<span class="sd"> ...</span>
|
||
<span class="sd"> ValueError: n must be >= 0</span>
|
||
|
||
<span class="sd"> Factorials of floats are OK, but the float must be an exact integer:</span>
|
||
<span class="sd"> >>> factorial(30.1)</span>
|
||
<span class="sd"> Traceback (most recent call last):</span>
|
||
<span class="sd"> ...</span>
|
||
<span class="sd"> ValueError: n must be exact integer</span>
|
||
<span class="sd"> >>> factorial(30.0)</span>
|
||
<span class="sd"> 265252859812191058636308480000000</span>
|
||
|
||
<span class="sd"> It must also not be ridiculously large:</span>
|
||
<span class="sd"> >>> factorial(1e100)</span>
|
||
<span class="sd"> Traceback (most recent call last):</span>
|
||
<span class="sd"> ...</span>
|
||
<span class="sd"> OverflowError: n too large</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="kn">import</span> <span class="nn">math</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">n</span> <span class="o">>=</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"n must be >= 0"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">math</span><span class="o">.</span><span class="n">floor</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">!=</span> <span class="n">n</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"n must be exact integer"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">n</span><span class="o">+</span><span class="mi">1</span> <span class="o">==</span> <span class="n">n</span><span class="p">:</span> <span class="c1"># catch a value like 1e300</span>
|
||
<span class="k">raise</span> <span class="ne">OverflowError</span><span class="p">(</span><span class="s2">"n too large"</span><span class="p">)</span>
|
||
<span class="n">result</span> <span class="o">=</span> <span class="mi">1</span>
|
||
<span class="n">factor</span> <span class="o">=</span> <span class="mi">2</span>
|
||
<span class="k">while</span> <span class="n">factor</span> <span class="o"><=</span> <span class="n">n</span><span class="p">:</span>
|
||
<span class="n">result</span> <span class="o">*=</span> <span class="n">factor</span>
|
||
<span class="n">factor</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
<span class="k">return</span> <span class="n">result</span>
|
||
|
||
|
||
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||
<span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">()</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-19">如果直接从命令行运行<code class="file docutils literal"><span class="pre">example.py</span></code>,则<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>可以发挥其魔力:</span></p><div class="highlight-shell-session"><div class="highlight"><pre><span></span><span class="gp">$</span> python example.py
|
||
<span class="gp">$</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-20">没有输出!</span><span class="yiyi-st" id="yiyi-21">这是正常的,它代表所有的示例正常工作。</span><span class="yiyi-st" id="yiyi-22">将<code class="docutils literal"><span class="pre">-v</span></code>传递给脚本,可以获得<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>的详细日志,并打印摘要:</span></p><div class="highlight-shell-session"><div class="highlight"><pre><span></span><span class="gp">$</span> python example.py -v
|
||
<span class="go">Trying:</span>
|
||
<span class="go"> factorial(5)</span>
|
||
<span class="go">Expecting:</span>
|
||
<span class="go"> 120</span>
|
||
<span class="go">ok</span>
|
||
<span class="go">Trying:</span>
|
||
<span class="go"> [factorial(n) for n in range(6)]</span>
|
||
<span class="go">Expecting:</span>
|
||
<span class="go"> [1, 1, 2, 6, 24, 120]</span>
|
||
<span class="go">ok</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-23">以此类推。结尾是:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>Trying:
|
||
factorial(1e100)
|
||
Expecting:
|
||
Traceback (most recent call last):
|
||
...
|
||
OverflowError: n too large
|
||
ok
|
||
2 items passed all tests:
|
||
1 tests in __main__
|
||
8 tests in __main__.factorial
|
||
9 tests in 2 items.
|
||
9 passed and 0 failed.
|
||
Test passed.
|
||
$
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-24">知道这些就够了,开始体验高效的<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>吧!</span><span class="yiyi-st" id="yiyi-25">当然可以更深入了解这个模块。</span><span class="yiyi-st" id="yiyi-26">以下部分提供完整的详细信息。</span><span class="yiyi-st" id="yiyi-27">请注意,标准Python测试套件和库中有很多文档测试的例子。</span><span class="yiyi-st" id="yiyi-28">特别有用的例子可以在标准测试文件<code class="file docutils literal"><span class="pre">Lib/test/test_doctest.py</span></code>中找到。</span></p><div class="section" id="simple-usage-checking-examples-in-docstrings"><h2><span class="yiyi-st" id="yiyi-29">26.3.1. </span><span class="yiyi-st" id="yiyi-30">简单的用法:检测文档字符串中的示例</span></h2><p><span class="yiyi-st" id="yiyi-31">使用doctest最简单的(但不是唯一的)方式就是在模块<code class="xref py py-mod docutils literal"><span class="pre">M</span></code>结尾添加:</span></p><pre><code class="language-python"><span></span><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||
<span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">()</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-32"><a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>将会检测模块<code class="xref py py-mod docutils literal"><span class="pre">M</span></code>中的文档字符串。</span></p><p><span class="yiyi-st" id="yiyi-33">当模块作为脚本运行时,文档字符串中的示例将被执行和验证:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="n">M</span><span class="o">.</span><span class="n">py</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-34">如果示例被验证正确,将不会显示任何内容。如果出现错误,错误的示例和错误的原因将打印到stdout。输出的最后一行是<code class="docutils literal"><span class="pre">***Test</span> <span class="pre">Failed***</span> <span class="pre">N</span> <span class="pre">failures.</span></code>,其中<em>N</em>是失败的示例个数。</span></p><p><span class="yiyi-st" id="yiyi-35">使用<code class="docutils literal"><span class="pre">-v</span></code>参数运行:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="n">M</span><span class="o">.</span><span class="n">py</span> <span class="o">-</span><span class="n">v</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-36">将会打印详细的示例调用信息,以及末尾的分类摘要。</span></p><p><span class="yiyi-st" id="yiyi-37">您可以通过将<code class="docutils literal"><span class="pre">verbose = True</span></code>传递给<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>来指定详细模式,或者通过传递<code class="docutils literal"><span class="pre">verbose = False</span></code>来禁止它。</span><span class="yiyi-st" id="yiyi-38">在任何一种情况下,<code class="docutils literal"><span class="pre">sys.argv</span></code>都不会被<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>检查(所以传递<code class="docutils literal"><span class="pre">-v</span></code>或者没有影响)。</span></p><p><span class="yiyi-st" id="yiyi-39">还有一个用于运行<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>的命令行快捷方式。</span><span class="yiyi-st" id="yiyi-40">您可以指示Python解释器直接从标准库运行doctest模块,并在命令行上传递模块名称:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">doctest</span> <span class="o">-</span><span class="n">v</span> <span class="n">example</span><span class="o">.</span><span class="n">py</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-41">这将导入<code class="file docutils literal"><span class="pre">example.py</span></code>作为独立模块并在其上运行<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>。</span><span class="yiyi-st" id="yiyi-42">请注意,如果文件是软件包的一部分并从该软件包导入其他子模块,则可能无法正常工作。</span></p><p><span class="yiyi-st" id="yiyi-43">有关<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>的更多信息,请参阅<a class="reference internal" href="#doctest-basic-api"><span>Basic API</span></a>部分。</span></p></div><div class="section" id="simple-usage-checking-examples-in-a-text-file"><h2><span class="yiyi-st" id="yiyi-44">26.3.2. </span><span class="yiyi-st" id="yiyi-45">简单的用法:通过文本文件检测示例</span></h2><p><span class="yiyi-st" id="yiyi-46">doctest的另一个简单应用是在文本文件中测试交互式示例。</span><span class="yiyi-st" id="yiyi-47">这可以通过<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>函数完成:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="n">doctest</span><span class="o">.</span><span class="n">testfile</span><span class="p">(</span><span class="s2">"example.txt"</span><span class="p">)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-48">该短脚本执行并验证文件<code class="file docutils literal"><span class="pre">example.txt</span></code>中包含的任何交互式Python示例。</span><span class="yiyi-st" id="yiyi-49">文件内容被视为一个巨大的文档字符串;该文件不需要包含Python程序!</span><span class="yiyi-st" id="yiyi-50">例如,也许<code class="file docutils literal"><span class="pre">example.txt</span></code>包含这个:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>The ``example`` module
|
||
======================
|
||
|
||
Using ``factorial``
|
||
-------------------
|
||
|
||
This is an example text file in reStructuredText format. First import
|
||
``factorial`` from the ``example`` module:
|
||
|
||
>>> from example import factorial
|
||
|
||
Now use it:
|
||
|
||
>>> factorial(6)
|
||
120
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-51">运行<code class="docutils literal"><span class="pre">doctest.testfile("example.txt")</span></code>,然后在此文档中找到错误:</span></p><pre><code class="language-python"><span></span><span class="n">File</span> <span class="s2">"./example.txt"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">14</span><span class="p">,</span> <span class="ow">in</span> <span class="n">example</span><span class="o">.</span><span class="n">txt</span>
|
||
<span class="n">Failed</span> <span class="n">example</span><span class="p">:</span>
|
||
<span class="n">factorial</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
|
||
<span class="n">Expected</span><span class="p">:</span>
|
||
<span class="mi">120</span>
|
||
<span class="n">Got</span><span class="p">:</span>
|
||
<span class="mi">720</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-52">和<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>一样,除非一个示例失败,否则<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>不会显示任何内容。</span><span class="yiyi-st" id="yiyi-53">如果一个例子失败,那么使用与<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>相同的格式将失败的例子和失败的原因输出到stdout。</span></p><p><span class="yiyi-st" id="yiyi-54">默认情况下,<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>在调用模块的目录中查找文件。</span><span class="yiyi-st" id="yiyi-55">有关可用于指示其在其他位置查找文件的可选参数的说明,请参阅<a class="reference internal" href="#doctest-basic-api"><span>Basic API</span></a>一节。</span></p><p><span class="yiyi-st" id="yiyi-56">Like <a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>, <a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>‘s verbosity can be set with the <code class="docutils literal"><span class="pre">-v</span></code> command-line switch or with the optional keyword argument <em>verbose</em>.</span></p><p><span class="yiyi-st" id="yiyi-57">还有一个用于运行<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>的命令行快捷方式。</span><span class="yiyi-st" id="yiyi-58">您可以指示Python解释器直接从标准库运行doctest模块,并在命令行上传递文件名:</span></p><pre><code class="language-python"><span></span><span class="n">python</span> <span class="o">-</span><span class="n">m</span> <span class="n">doctest</span> <span class="o">-</span><span class="n">v</span> <span class="n">example</span><span class="o">.</span><span class="n">txt</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-59">由于文件名不以<code class="file docutils literal"><span class="pre">.py</span></code>结尾,因此<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>推断它必须与<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>一起运行,而不是<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-60">有关<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>的更多信息,请参阅<a class="reference internal" href="#doctest-basic-api"><span>Basic API</span></a>部分。</span></p></div><div class="section" id="how-it-works"><h2><span class="yiyi-st" id="yiyi-61">26.3.3. </span><span class="yiyi-st" id="yiyi-62">它如何工作</span></h2><p><span class="yiyi-st" id="yiyi-63">本节将详细介绍doctest如何工作:查看哪节文档字符串,如何查找交互式示例,使用的执行上下文,如何处理异常以及如何使用选项标志来控制其行为。</span><span class="yiyi-st" id="yiyi-64">这是编写doctest示例时需要了解的信息;有关在这些示例上实际运行doctest的信息,请参阅以下各节。</span></p><div class="section" id="which-docstrings-are-examined"><h3><span class="yiyi-st" id="yiyi-65">26.3.3.1. </span><span class="yiyi-st" id="yiyi-66">哪些Docstrings被检查?</span></h3><p><span class="yiyi-st" id="yiyi-67">模块docstring,以及所有函数,类和方法文档字符串被搜索。</span><span class="yiyi-st" id="yiyi-68">导入到模块中的对象不被搜索。</span></p><p><span class="yiyi-st" id="yiyi-69">另外,如果<code class="docutils literal"><span class="pre">M.__test__</span></code>存在且“为真”,则它必须是字典,并且每个条目将(字符串)名称映射到函数对象,类对象或字符串。</span><span class="yiyi-st" id="yiyi-70">搜索从<code class="docutils literal"><span class="pre">M.__test__</span></code>中找到的函数和类对象文档字符串,并将字符串视为它们是文档字符串。</span><span class="yiyi-st" id="yiyi-71">在输出中,<code class="docutils literal"><span class="pre">M.__test__</span></code>中的键<code class="docutils literal"><span class="pre">K</span></code>显示名称</span></p><pre><code class="language-python"><span></span><span class="o"><</span><span class="n">name</span> <span class="n">of</span> <span class="n">M</span><span class="o">>.</span><span class="n">__test__</span><span class="o">.</span><span class="n">K</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-72">找到的任何类都以相似的方式递归搜索,以测试其包含的方法和嵌套类中的文档字符串。</span></p><div class="impl-detail compound"><p><span class="yiyi-st" id="yiyi-73"><strong>CPython implementation detail:</strong> Prior to version 3.4, extension modules written in C were not fully searched by doctest.</span></p></div></div><div class="section" id="how-are-docstring-examples-recognized"><h3><span class="yiyi-st" id="yiyi-74">26.3.3.2. </span><span class="yiyi-st" id="yiyi-75">Docstring示例如何识别?</span></h3><p><span class="yiyi-st" id="yiyi-76">在大多数情况下,交互式控制台会话的复制和粘贴工作正常,但doctest并不试图精确模拟任何特定的Python shell。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="c1"># comments are ignored</span>
|
||
<span class="gp">>>> </span><span class="n">x</span> <span class="o">=</span> <span class="mi">12</span>
|
||
<span class="gp">>>> </span><span class="n">x</span>
|
||
<span class="go">12</span>
|
||
<span class="gp">>>> </span><span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">13</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"yes"</span><span class="p">)</span>
|
||
<span class="gp">... </span><span class="k">else</span><span class="p">:</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"no"</span><span class="p">)</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"NO"</span><span class="p">)</span>
|
||
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"NO!!!"</span><span class="p">)</span>
|
||
<span class="gp">...</span>
|
||
<span class="go">no</span>
|
||
<span class="go">NO</span>
|
||
<span class="go">NO!!!</span>
|
||
<span class="go">>>></span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-77">Any expected output must immediately follow the final <code class="docutils literal"><span class="pre">'>>></span> <span class="pre">'</span></code> or <code class="docutils literal"><span class="pre">'...</span> <span class="pre">'</span></code> line containing the code, and the expected output (if any) extends to the next <code class="docutils literal"><span class="pre">'>>></span> <span class="pre">'</span></code> or all-whitespace line.</span></p><p><span class="yiyi-st" id="yiyi-78">细则:</span></p><ul><li><p class="first"><span class="yiyi-st" id="yiyi-79">预期的输出不能包含全空白行,因为这样的行被用来表示预期输出的结束。</span><span class="yiyi-st" id="yiyi-80">如果预期输出一定要包含空行,请在您的doctest示例中将<code class="docutils literal"><span class="pre"><BLANKLINE></span></code>放在每个空白行。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-81">所有Tab字符将会被扩展为空格,使用8列制表符。</span><span class="yiyi-st" id="yiyi-82">测试代码生成的输出中的tab不会被修改。</span><span class="yiyi-st" id="yiyi-83">因为示例输出中的任何hard tab都是<em>展开</em>的,这意味着如果代码输出包含hard tab,则doctest可以传递的唯一方式就是<a class="reference internal" href="#doctest.NORMALIZE_WHITESPACE" title="doctest.NORMALIZE_WHITESPACE"><code class="xref py py-const docutils literal"><span class="pre">NORMALIZE_WHITESPACE</span></code></a>选项或<a class="reference internal" href="#doctest-directives"><span>指令</span></a>有效。</span><span class="yiyi-st" id="yiyi-84">或者,可以重写测试以捕获输出并将其作为测试的一部分与预期值进行比较。</span><span class="yiyi-st" id="yiyi-85">源代码中对制表符的处理是通过反复试验得出的,并且已被证明是处理它们的最不容易出错的方式。</span><span class="yiyi-st" id="yiyi-86">可以通过编写一个自定义的<a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a>类来使用不同的算法来处理选项卡。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-87">输出到标准输出被捕获,但不输出到标准错误(异常追溯通过不同的方式捕获)。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-88">如果在交互式会话中通过反斜线继续行,或者出于任何其他原因使用反斜杠,则应该使用原始文档字符串,该字符串将按照输入时的顺序保留反斜杠:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="sd">r'''Backslashes in a raw docstring: m\n'''</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">__doc__</span><span class="p">)</span>
|
||
<span class="go">Backslashes in a raw docstring: m\n</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-89">否则,反斜杠将被解释为字符串的一部分。</span><span class="yiyi-st" id="yiyi-90">例如,上面的<code class="docutils literal"><span class="pre">\n</span></code>将被解释为换行符。</span><span class="yiyi-st" id="yiyi-91">或者,您可以在doctest版本中将每个反斜杠加倍(并且不使用原始字符串):</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
|
||
<span class="gp">... </span> <span class="sd">'''Backslashes in a raw docstring: m\\n'''</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">__doc__</span><span class="p">)</span>
|
||
<span class="go">Backslashes in a raw docstring: m\n</span>
|
||
</code></pre></li><li><p class="first"><span class="yiyi-st" id="yiyi-92">起始栏无关紧要:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">assert</span> <span class="s2">"Easy!"</span>
|
||
<span class="go"> >>> import math</span>
|
||
<span class="go"> >>> math.floor(1.9)</span>
|
||
<span class="go"> 1</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-93">并且从最初的<code class="docutils literal"><span class="pre">>&gt;&gt;&gt;</span> <span class="pre">'</span></code>行中出现的预期输出中除去了许多前导空白字符,例。</span></p></li></ul></div><div class="section" id="what-s-the-execution-context"><h3><span class="yiyi-st" id="yiyi-94">26.3.3.3. </span><span class="yiyi-st" id="yiyi-95">什么是执行上下文?</span></h3><p><span class="yiyi-st" id="yiyi-96">By default, each time <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> finds a docstring to test, it uses a <em>shallow copy</em> of <code class="xref py py-mod docutils literal"><span class="pre">M</span></code>‘s globals, so that running tests doesn’t change the module’s real globals, and so that one test in <code class="xref py py-mod docutils literal"><span class="pre">M</span></code> can’t leave behind crumbs that accidentally allow another test to work. </span><span class="yiyi-st" id="yiyi-97">这意味着示例可以自由使用<code class="xref py py-mod docutils literal"><span class="pre">M</span></code>中顶层定义的任何名称,以及正在运行的文档字符串中已定义的名称。</span><span class="yiyi-st" id="yiyi-98">示例无法看到其他文档中定义的名称。</span></p><p><span class="yiyi-st" id="yiyi-99">您可以通过将<code class="docutils literal"><span class="pre">globs=your_dict</span></code>传递给<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>或<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>来强制使用自己的dict作为执行上下文。</span></p></div><div class="section" id="what-about-exceptions"><h3><span class="yiyi-st" id="yiyi-100">26.3.3.4. </span><span class="yiyi-st" id="yiyi-101">如何处理异常?</span></h3><p><span class="yiyi-st" id="yiyi-102">没问题,只要回溯是该示例生成的唯一输出:只需粘贴回溯。</span><span class="yiyi-st" id="yiyi-103"><a class="footnote-reference" href="#id2" id="id1">[1]</a> Since tracebacks contain details that are likely to change rapidly (for example, exact file paths and line numbers), this is one case where doctest works hard to be flexible in what it accepts.</span></p><p><span class="yiyi-st" id="yiyi-104">简单的例子:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
||
<span class="gr">ValueError</span>: <span class="n">list.remove(x): x not in list</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-105">That doctest succeeds if <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a> is raised, with the <code class="docutils literal"><span class="pre">list.remove(x):</span> <span class="pre">x</span> <span class="pre">not</span> <span class="pre">in</span> <span class="pre">list</span></code> detail as shown.</span></p><p><span class="yiyi-st" id="yiyi-106">预期的异常输出必须以追溯标题开头,该标题可以是以下两行中的任一行,缩写与示例的第一行相同:</span></p><pre><code class="language-python"><span></span><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
|
||
<span class="n">Traceback</span> <span class="p">(</span><span class="n">innermost</span> <span class="n">last</span><span class="p">):</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-107">traceback头后面跟着一个可选的traceback堆栈,其内容被doctest忽略。</span><span class="yiyi-st" id="yiyi-108">回溯堆栈通常被忽略,或者从交互式会话逐字复制。</span></p><p><span class="yiyi-st" id="yiyi-109">跟踪堆栈后面是最有趣的部分:包含异常类型和细节的行。</span><span class="yiyi-st" id="yiyi-110">这通常是追溯的最后一行,但如果异常具有多行详细信息,则可以跨越多行:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'multi</span><span class="se">\n</span><span class="s1"> line</span><span class="se">\n</span><span class="s1">detail'</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
||
<span class="gr">ValueError</span>: <span class="n">multi</span>
|
||
<span class="go"> line</span>
|
||
<span class="go">detail</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-111">最后三行(以<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>开始)与异常的类型和详细信息进行比较,其余部分将被忽略。</span></p><p><span class="yiyi-st" id="yiyi-112">最佳做法是省略追溯堆栈,除非它为示例增加了重要的文档值。</span><span class="yiyi-st" id="yiyi-113">所以最后一个例子可能更好,因为:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'multi</span><span class="se">\n</span><span class="s1"> line</span><span class="se">\n</span><span class="s1">detail'</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
<span class="o">...</span>
|
||
<span class="gr">ValueError</span>: <span class="n">multi</span>
|
||
<span class="go"> line</span>
|
||
<span class="go">detail</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-114">请注意,回溯处理非常特别。</span><span class="yiyi-st" id="yiyi-115">特别是在重写的例子中,<code class="docutils literal"><span class="pre">...</span></code>的使用与doctest的<a class="reference internal" href="#doctest.ELLIPSIS" title="doctest.ELLIPSIS"><code class="xref py py-const docutils literal"><span class="pre">ELLIPSIS</span></code></a>选项无关。</span><span class="yiyi-st" id="yiyi-116">这个例子中的省略号可以省略,或者可以是三个(或三百个)逗号或数字,或者Monty Python skit的缩进记录。</span></p><p><span class="yiyi-st" id="yiyi-117">一些细节你应该阅读一次,但不需要记住:</span></p><ul><li><p class="first"><span class="yiyi-st" id="yiyi-118">Doctest无法猜测您的预期输出是来自异常追溯还是来自普通打印。</span><span class="yiyi-st" id="yiyi-119">So, e.g., an example that expects <code class="docutils literal"><span class="pre">ValueError:</span> <span class="pre">42</span> <span class="pre">is</span> <span class="pre">prime</span></code> will pass whether <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a> is actually raised or if the example merely prints that traceback text. </span><span class="yiyi-st" id="yiyi-120">实际上,普通输出很少以追溯标题行开始,所以这不会产生实际问题。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-121">回溯堆栈行(如果存在)必须比示例的首行缩进更多,<em>或</em>以非字母数字字符开头。</span><span class="yiyi-st" id="yiyi-122">追溯标题后面的第一行缩写相同,并以字母数字开头,作为异常详细信息的开始。</span><span class="yiyi-st" id="yiyi-123">当然这对于真正的回溯来说是正确的。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-124">指定了<a class="reference internal" href="#doctest.IGNORE_EXCEPTION_DETAIL" title="doctest.IGNORE_EXCEPTION_DETAIL"><code class="xref py py-const docutils literal"><span class="pre">IGNORE_EXCEPTION_DETAIL</span></code></a> doctest选项时,将忽略最左侧冒号后面的所有内容以及异常名称中的所有模块信息。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-125">交互式shell省略了一些<a class="reference internal" href="exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxError</span></code></a>的traceback标题行。但doctest使用traceback标题行来区分异常和非异常。</span><span class="yiyi-st" id="yiyi-126">因此,在极少数情况下,如果您需要测试省略traceback头的<a class="reference internal" href="exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxError</span></code></a>,则需要手动将traceback标题行添加到测试示例中。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-127">对于某些<a class="reference internal" href="exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxError</span></code></a>,Python使用<code class="docutils literal"><span class="pre">^</span></code>标记来显示语法错误的字符位置:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="mi">1</span> <span class="mi">1</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>
|
||
<span class="mi">1</span> <span class="mi">1</span>
|
||
<span class="o">^</span>
|
||
<span class="gr">SyntaxError</span>: <span class="n">invalid syntax</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-128">由于显示错误位置的行出现在异常类型和细节之前,因此它们不会被doctest检查。</span><span class="yiyi-st" id="yiyi-129">例如,即使将<code class="docutils literal"><span class="pre">^</span></code>标记放在错误的位置,也会通过以下测试:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="mi">1</span> <span class="mi">1</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>
|
||
<span class="mi">1</span> <span class="mi">1</span>
|
||
<span class="o">^</span>
|
||
<span class="gr">SyntaxError</span>: <span class="n">invalid syntax</span>
|
||
</code></pre></li></ul></div><div class="section" id="option-flags"><h3><span class="yiyi-st" id="yiyi-130">26.3.3.5. </span><span class="yiyi-st" id="yiyi-131">选项标志</span></h3><p><span class="yiyi-st" id="yiyi-132">一些选项可以用于控制doctest行为。</span><span class="yiyi-st" id="yiyi-133">标志的符号名称作为模块常量提供,可以组合在一起并传递给各种功能。</span><span class="yiyi-st" id="yiyi-134">这些名称也可以在<a class="reference internal" href="#doctest-directives"><span>doctest directives</span></a>中使用,并可以通过<code class="docutils literal"><span class="pre">-o</span></code>选项传递给doctest命令行界面。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-135"><span class="versionmodified">版本3.4中的新功能:</span> <code class="docutils literal"><span class="pre">-o</span></code>命令行选项。</span></p></div><p><span class="yiyi-st" id="yiyi-136">第一组选项定义测试语义,控制doctest如何确定实际输出是否与示例预期输出相匹配的方面:</span></p><dl class="data"><dt id="doctest.DONT_ACCEPT_TRUE_FOR_1"><span class="yiyi-st" id="yiyi-137"><code class="descclassname">文档测试 T0> <code class="descname"> DONT_ACCEPT_TRUE_FOR_1 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-138">默认情况下,如果期望的输出块仅包含<code class="docutils literal"><span class="pre">1</span></code>,则包含<code class="docutils literal"><span class="pre">1</span></code>或<code class="docutils literal"><span class="pre">True</span></code>的实际输出块被认为是匹配的,对于<code class="docutils literal"><span class="pre">0</span></code>与<code class="docutils literal"><span class="pre">False</span></code>类似。</span><span class="yiyi-st" id="yiyi-139">当指定了<a class="reference internal" href="#doctest.DONT_ACCEPT_TRUE_FOR_1" title="doctest.DONT_ACCEPT_TRUE_FOR_1"><code class="xref py py-const docutils literal"><span class="pre">DONT_ACCEPT_TRUE_FOR_1</span></code></a>时,不允许替换。</span><span class="yiyi-st" id="yiyi-140">缺省行为迎合了Python将许多函数的返回类型从整数更改为布尔值;希望“小整数”输出的doctests在这些情况下仍然有效。</span><span class="yiyi-st" id="yiyi-141">这个选项可能会消失,但不会持续数年。</span></p></dd></dl><dl class="data"><dt id="doctest.DONT_ACCEPT_BLANKLINE"><span class="yiyi-st" id="yiyi-142"><code class="descclassname">文档测试 T0> <code class="descname"> DONT_ACCEPT_BLANKLINE T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-143">默认情况下,如果预期的输出块包含仅包含字符串<code class="docutils literal"><span class="pre"><BLANKLINE></span></code>的行,那么该行将匹配实际输出中的空白行。</span><span class="yiyi-st" id="yiyi-144">由于真正的空行界定了预期的输出,因此这是沟通预期空行的唯一方式。</span><span class="yiyi-st" id="yiyi-145">当指定<a class="reference internal" href="#doctest.DONT_ACCEPT_BLANKLINE" title="doctest.DONT_ACCEPT_BLANKLINE"><code class="xref py py-const docutils literal"><span class="pre">DONT_ACCEPT_BLANKLINE</span></code></a>时,不允许此替换。</span></p></dd></dl><dl class="data"><dt id="doctest.NORMALIZE_WHITESPACE"><span class="yiyi-st" id="yiyi-146"><code class="descclassname">文档测试 T0> <code class="descname"> NORMALIZE_WHITESPACE T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-147">指定时,所有空白(空格和换行符)都被视为相等。</span><span class="yiyi-st" id="yiyi-148">预期输出中的任何空白序列都将与实际输出中的任何空白序列相匹配。</span><span class="yiyi-st" id="yiyi-149">默认情况下,空白必须完全匹配。</span><span class="yiyi-st" id="yiyi-150"><a class="reference internal" href="#doctest.NORMALIZE_WHITESPACE" title="doctest.NORMALIZE_WHITESPACE"><code class="xref py py-const docutils literal"><span class="pre">NORMALIZE_WHITESPACE</span></code></a> is especially useful when a line of expected output is very long, and you want to wrap it across multiple lines in your source.</span></p></dd></dl><dl class="data"><dt id="doctest.ELLIPSIS"><span class="yiyi-st" id="yiyi-151"><code class="descclassname">文档测试 T0> <code class="descname">省略号 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-152">指定时,预期输出中的省略号标记(<code class="docutils literal"><span class="pre">...</span></code>)可以匹配实际输出中的任何子字符串。</span><span class="yiyi-st" id="yiyi-153">这包括跨越行边界的子字符串和空的子字符串,所以最好保持简单的使用。</span><span class="yiyi-st" id="yiyi-154">复杂的用法可能导致相同种类的“oops,它太匹配了!”意外的是,<code class="docutils literal"><span class="pre">.*</span></code>很容易出现在正则表达式中。</span></p></dd></dl><dl class="data"><dt id="doctest.IGNORE_EXCEPTION_DETAIL"><span class="yiyi-st" id="yiyi-155"><code class="descclassname">文档测试 T0> <code class="descname"> IGNORE_EXCEPTION_DETAIL T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-156">如果指定这个选项,那么当引发的异常的类型与期望的异常类型相同就可以通过的,不会检测异常的详细信息。</span><span class="yiyi-st" id="yiyi-157">例如,如果引发的实际异常是<code class="docutils literal"><span class="pre">ValueError:</span>,则会通过一个期望<code class="docutils literal"><span class="pre">ValueError:</span> <span class="pre">42</span> <span class="pre">3 * 14</span></code></code>,但会失败,例如,如果发生<a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal"><span class="pre">TypeError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-158">它也会忽略Python 3 doctest报告中使用的模块名称。</span><span class="yiyi-st" id="yiyi-159">因此,无论测试是在Python 2.7还是Python 3.2(或更高版本)下运行,这两种变体都可以与指定的标志一起使用:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="k">raise</span> <span class="n">CustomError</span><span class="p">(</span><span class="s1">'message'</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
<span class="gr">CustomError</span>: <span class="n">message</span>
|
||
|
||
<span class="gp">>>> </span><span class="k">raise</span> <span class="n">CustomError</span><span class="p">(</span><span class="s1">'message'</span><span class="p">)</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
<span class="gr">my_module.CustomError</span>: <span class="n">message</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-160">Note that <a class="reference internal" href="#doctest.ELLIPSIS" title="doctest.ELLIPSIS"><code class="xref py py-const docutils literal"><span class="pre">ELLIPSIS</span></code></a> can also be used to ignore the details of the exception message, but such a test may still fail based on whether or not the module details are printed as part of the exception name. </span><span class="yiyi-st" id="yiyi-161">Using <a class="reference internal" href="#doctest.IGNORE_EXCEPTION_DETAIL" title="doctest.IGNORE_EXCEPTION_DETAIL"><code class="xref py py-const docutils literal"><span class="pre">IGNORE_EXCEPTION_DETAIL</span></code></a> and the details from Python 2.3 is also the only clear way to write a doctest that doesn’t care about the exception detail yet continues to pass under Python 2.3 or earlier (those releases do not support <a class="reference internal" href="#doctest-directives"><span>doctest directives</span></a> and ignore them as irrelevant comments). </span><span class="yiyi-st" id="yiyi-162">例如:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'moo'</span>
|
||
<span class="gt">Traceback (most recent call last):</span>
|
||
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n">?</span>
|
||
<span class="gr">TypeError</span>: <span class="n">object doesn't support item assignment</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-163">虽然Python 2.4中的细节更改为“不”而不是“不”,但在Python 2.3以及更高版本的Python版本中通过了指定的标志。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-164"><span class="versionmodified">Changed in version 3.2: </span><a class="reference internal" href="#doctest.IGNORE_EXCEPTION_DETAIL" title="doctest.IGNORE_EXCEPTION_DETAIL"><code class="xref py py-const docutils literal"><span class="pre">IGNORE_EXCEPTION_DETAIL</span></code></a> now also ignores any information relating to the module containing the exception under test.</span></p></div></dd></dl><dl class="data"><dt id="doctest.SKIP"><span class="yiyi-st" id="yiyi-165"><code class="descclassname">文档测试 T0> <code class="descname"> SKIP T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-166">指定时,请不要运行该示例。</span><span class="yiyi-st" id="yiyi-167">这在doctest示例既可用作文档也可用作测试用例的情况下非常有用,应将其用于文档目的,但不应进行检查。</span><span class="yiyi-st" id="yiyi-168">例如,该例子的输出可能是随机的;或者该示例可能依赖于测试驱动程序无法使用的资源。</span></p><p><span class="yiyi-st" id="yiyi-169">SKIP标志也可用于临时“注释”示例。</span></p></dd></dl><dl class="data"><dt id="doctest.COMPARISON_FLAGS"><span class="yiyi-st" id="yiyi-170"><code class="descclassname">文档测试 T0> <code class="descname"> COMPARISON_FLAGS T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-171">将上面的所有比较标志掩盖起来。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-172">第二组选项控制如何报告测试失败:</span></p><dl class="data"><dt id="doctest.REPORT_UDIFF"><span class="yiyi-st" id="yiyi-173"><code class="descclassname">文档测试 T0> <code class="descname"> REPORT_UDIFF T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-174">指定时,涉及多行预期和实际输出的故障将使用统一差异显示。</span></p></dd></dl><dl class="data"><dt id="doctest.REPORT_CDIFF"><span class="yiyi-st" id="yiyi-175"><code class="descclassname">文档测试 T0> <code class="descname"> REPORT_CDIFF T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-176">指定时,涉及多行预期输出和实际输出的故障将使用上下文差异显示。</span></p></dd></dl><dl class="data"><dt id="doctest.REPORT_NDIFF"><span class="yiyi-st" id="yiyi-177"><code class="descclassname">文档测试 T0> <code class="descname"> REPORT_NDIFF T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-178">When specified, differences are computed by <code class="docutils literal"><span class="pre">difflib.Differ</span></code>, using the same algorithm as the popular <code class="file docutils literal"><span class="pre">ndiff.py</span></code> utility. </span><span class="yiyi-st" id="yiyi-179">这是标记线内和线间差异的唯一方法。</span><span class="yiyi-st" id="yiyi-180">For example, if a line of expected output contains digit <code class="docutils literal"><span class="pre">1</span></code> where actual output contains letter <code class="docutils literal"><span class="pre">l</span></code>, a line is inserted with a caret marking the mismatching column positions.</span></p></dd></dl><dl class="data"><dt id="doctest.REPORT_ONLY_FIRST_FAILURE"><span class="yiyi-st" id="yiyi-181"><code class="descclassname">文档测试 T0> <code class="descname"> REPORT_ONLY_FIRST_FAILURE T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-182">指定时,显示每个doctest中的第一个失败示例,但禁止所有其他示例的输出。</span><span class="yiyi-st" id="yiyi-183">这将防止doctest报告因早期故障而中断的正确示例;但它也可能隐藏不正确的例子,不依靠第一次失败而失败。</span><span class="yiyi-st" id="yiyi-184">当指定<a class="reference internal" href="#doctest.REPORT_ONLY_FIRST_FAILURE" title="doctest.REPORT_ONLY_FIRST_FAILURE"><code class="xref py py-const docutils literal"><span class="pre">REPORT_ONLY_FIRST_FAILURE</span></code></a>时,其余示例仍在运行,并且仍计入报告的失败总数;只有输出被抑制。</span></p></dd></dl><dl class="data"><dt id="doctest.FAIL_FAST"><span class="yiyi-st" id="yiyi-185"><code class="descclassname">文档测试 T0> <code class="descname"> FAIL_FAST T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-186">指定时,在第一个失败示例之后退出,不要尝试运行其余示例。</span><span class="yiyi-st" id="yiyi-187">因此,报告的故障数最多为1。</span><span class="yiyi-st" id="yiyi-188">该标志在调试期间可能很有用,因为第一次故障后的示例甚至不会产生调试输出。</span></p><p><span class="yiyi-st" id="yiyi-189">doctest命令行接受选项<code class="docutils literal"><span class="pre">-f</span></code>作为<code class="docutils literal"><span class="pre">-o</span> <span class="pre">FAIL_FAST</span></code>的简写。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-190"><span class="versionmodified">版本3.4中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="doctest.REPORTING_FLAGS"><span class="yiyi-st" id="yiyi-191"><code class="descclassname">文档测试 T0> <code class="descname"> REPORTING_FLAGS T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-192">将上面的所有报告标记掩盖起来。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-193">还有一种方法可以注册新的选项标记名称,但除非您打算通过子类扩展<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>内部消息,否则这种方法并不有用:</span></p><dl class="function"><dt id="doctest.register_optionflag"><span class="yiyi-st" id="yiyi-194"><code class="descclassname">文档测试 T0> <code class="descname"> register_optionflag T1> <span class="sig-paren">( T2> <em>名称 T3> <span class="sig-paren">) T4> </span></em></span></code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-195">用给定名称创建一个新选项标志,并返回新标志的整数值。</span><span class="yiyi-st" id="yiyi-196"><a class="reference internal" href="#doctest.register_optionflag" title="doctest.register_optionflag"><code class="xref py py-func docutils literal"><span class="pre">register_optionflag()</span></code></a> can be used when subclassing <a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a> or <a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a> to create new options that are supported by your subclasses. </span><span class="yiyi-st" id="yiyi-197"><a class="reference internal" href="#doctest.register_optionflag" title="doctest.register_optionflag"><code class="xref py py-func docutils literal"><span class="pre">register_optionflag()</span></code></a> should always be called using the following idiom:</span></p><pre><code class="language-python"><span></span><span class="n">MY_FLAG</span> <span class="o">=</span> <span class="n">register_optionflag</span><span class="p">(</span><span class="s1">'MY_FLAG'</span><span class="p">)</span>
|
||
</code></pre></dd></dl></div><div class="section" id="directives"><h3><span class="yiyi-st" id="yiyi-198">26.3.3.6. </span><span class="yiyi-st" id="yiyi-199">指令</span></h3><p><span class="yiyi-st" id="yiyi-200">Doctest指令可用于修改单个示例的<a class="reference internal" href="#doctest-options"><span>option flags</span></a>。</span><span class="yiyi-st" id="yiyi-201">Doctest指令是遵循示例源代码的特殊Python注释:</span></p><pre>
|
||
<strong id="grammar-token-directive">directive </strong> ::= "#" "doctest:" <a class="reference internal" href="#grammar-token-directive_options"><code class="xref docutils literal"><span class="pre">directive_options</span></code></a>
|
||
<strong id="grammar-token-directive_options">directive_options </strong> ::= <a class="reference internal" href="#grammar-token-directive_option"><code class="xref docutils literal"><span class="pre">directive_option</span></code></a> ("," <a class="reference internal" href="#grammar-token-directive_option"><code class="xref docutils literal"><span class="pre">directive_option</span></code></a>)\*
|
||
<strong id="grammar-token-directive_option">directive_option </strong> ::= <a class="reference internal" href="#grammar-token-on_or_off"><code class="xref docutils literal"><span class="pre">on_or_off</span></code></a> <a class="reference internal" href="#grammar-token-directive_option_name"><code class="xref docutils literal"><span class="pre">directive_option_name</span></code></a>
|
||
<strong id="grammar-token-on_or_off">on_or_off </strong> ::= "+" \| "-"
|
||
<strong id="grammar-token-directive_option_name">directive_option_name</strong> ::= "DONT_ACCEPT_BLANKLINE" \| "NORMALIZE_WHITESPACE" \| ...
|
||
</pre><p><span class="yiyi-st" id="yiyi-202">在<code class="docutils literal"><span class="pre">+</span></code>或<code class="docutils literal"><span class="pre">-</span></code>和指令选项名称之间不允许有空格。</span><span class="yiyi-st" id="yiyi-203">指令选项名称可以是上面解释的任何选项标志名称。</span></p><p><span class="yiyi-st" id="yiyi-204">一个例子的doctest指令修改了doctest的这个例子的行为。</span><span class="yiyi-st" id="yiyi-205">使用<code class="docutils literal"><span class="pre">+</span></code>启用命名行为,或<code class="docutils literal"><span class="pre">-</span></code>将其禁用。</span></p><p><span class="yiyi-st" id="yiyi-206">例如,这个测试通过:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)))</span> <span class="c1"># doctest: +NORMALIZE_WHITESPACE</span>
|
||
<span class="go">[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,</span>
|
||
<span class="go">10, 11, 12, 13, 14, 15, 16, 17, 18, 19]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-207">如果没有指令,它会失败,这是因为实际输出在单个数字列表元素之前没有两个空格,并且因为实际输出在单行上。</span><span class="yiyi-st" id="yiyi-208">这个测试也通过了,并且还需要一个指令来做到这一点:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)))</span> <span class="c1"># doctest: +ELLIPSIS</span>
|
||
<span class="go">[0, 1, ..., 18, 19]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-209">多条指令可用于单条物理线路,用逗号分隔:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)))</span> <span class="c1"># doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE</span>
|
||
<span class="go">[0, 1, ..., 18, 19]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-210">如果单个示例使用多个指令注释,则将它们合并:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">20</span><span class="p">)))</span> <span class="c1"># doctest: +ELLIPSIS</span>
|
||
<span class="gp">... </span> <span class="c1"># doctest: +NORMALIZE_WHITESPACE</span>
|
||
<span class="go">[0, 1, ..., 18, 19]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-211">如前例所示,您可以将<code class="docutils literal"><span class="pre">...</span></code>行添加到仅包含指令的示例中。</span><span class="yiyi-st" id="yiyi-212">当一个例子对于指令很容易适合同一行时太长了,这会很有用:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">))</span> <span class="o">+</span> <span class="nb">list</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">)))</span>
|
||
<span class="gp">... </span><span class="c1"># doctest: +ELLIPSIS</span>
|
||
<span class="go">[0, ..., 4, 10, ..., 19, 30, ..., 39]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-213">请注意,由于默认情况下所有选项都被禁用,并且指令仅适用于它们出现的示例,因此启用选项(通过指令中的<code class="docutils literal"><span class="pre">+</span></code>)通常是唯一有意义的选择。</span><span class="yiyi-st" id="yiyi-214">但是,选项标志也可以传递给运行doctests的函数,建立不同的默认值。</span><span class="yiyi-st" id="yiyi-215">在这种情况下,通过<code class="docutils literal"><span class="pre">-</span></code>在指令中禁用选项可能很有用。</span></p></div><div class="section" id="warnings"><h3><span class="yiyi-st" id="yiyi-216">26.3.3.7. </span><span class="yiyi-st" id="yiyi-217">警告</span></h3><p><span class="yiyi-st" id="yiyi-218"><a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> is serious about requiring exact matches in expected output. </span><span class="yiyi-st" id="yiyi-219">如果即使单个字符不匹配,测试也会失败。</span><span class="yiyi-st" id="yiyi-220">这可能会让你感到惊讶,因为你确切地知道Python做了什么,并且不能保证输出。</span><span class="yiyi-st" id="yiyi-221">例如,在打印字典时,Python不保证键值对将以任何特定的顺序打印,因此像</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">foo</span><span class="p">()</span>
|
||
<span class="go">{"Hermione": "hippogryph", "Harry": "broomstick"}</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-222">很脆弱!</span><span class="yiyi-st" id="yiyi-223">一种解决方法是做</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">foo</span><span class="p">()</span> <span class="o">==</span> <span class="p">{</span><span class="s2">"Hermione"</span><span class="p">:</span> <span class="s2">"hippogryph"</span><span class="p">,</span> <span class="s2">"Harry"</span><span class="p">:</span> <span class="s2">"broomstick"</span><span class="p">}</span>
|
||
<span class="go">True</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-224">代替。</span><span class="yiyi-st" id="yiyi-225">另一个是要做的</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">foo</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
||
<span class="gp">>>> </span><span class="n">d</span>
|
||
<span class="go">[('Harry', 'broomstick'), ('Hermione', 'hippogryph')]</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-226">还有其他的,但你明白了。</span></p><p><span class="yiyi-st" id="yiyi-227">另一个不好的想法是打印嵌入对象地址的东西,比如</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="nb">id</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span> <span class="c1"># certain to fail some of the time</span>
|
||
<span class="go">7948648</span>
|
||
<span class="gp">>>> </span><span class="k">class</span> <span class="nc">C</span><span class="p">:</span> <span class="k">pass</span>
|
||
<span class="gp">>>> </span><span class="n">C</span><span class="p">()</span> <span class="c1"># the default repr() for instances embeds an address</span>
|
||
<span class="go"><__main__.C instance at 0x00AC18F0></span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-228"><a class="reference internal" href="#doctest.ELLIPSIS" title="doctest.ELLIPSIS"><code class="xref py py-const docutils literal"><span class="pre">ELLIPSIS</span></code></a>指令为最后一个例子提供了一个很好的方法:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">C</span><span class="p">()</span> <span class="c1">#doctest: +ELLIPSIS</span>
|
||
<span class="go"><__main__.C instance at 0x...></span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-229">浮点数也受到跨平台的小输出变化的影响,因为Python遵循平台C库进行浮点格式化,而C库在质量上差别很大。</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="mf">1.</span><span class="o">/</span><span class="mi">7</span> <span class="c1"># risky</span>
|
||
<span class="go">0.14285714285714285</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="mf">1.</span><span class="o">/</span><span class="mi">7</span><span class="p">)</span> <span class="c1"># safer</span>
|
||
<span class="go">0.142857142857</span>
|
||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="mf">1.</span><span class="o">/</span><span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">))</span> <span class="c1"># much safer</span>
|
||
<span class="go">0.142857</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-230">在所有平台上,<code class="docutils literal"><span class="pre">I/2.**J</span></code>形式的数字都是安全的,而且我通常会设计一些doctest例子来生成这种形式的数字:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="mf">3.</span><span class="o">/</span><span class="mi">4</span> <span class="c1"># utterly safe</span>
|
||
<span class="go">0.75</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-231">简单的分数对于人们来说也更容易理解,并且这使得更好的文档。</span></p></div></div><div class="section" id="basic-api"><h2><span class="yiyi-st" id="yiyi-232">26.3.4. </span><span class="yiyi-st" id="yiyi-233">基本API </span></h2><p><span class="yiyi-st" id="yiyi-234">The functions <a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a> and <a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a> provide a simple interface to doctest that should be sufficient for most basic uses. </span><span class="yiyi-st" id="yiyi-235">有关这两个函数的不太正式的介绍,请参见<a class="reference internal" href="#doctest-simple-testmod"><span>Simple Usage: Checking Examples in Docstrings</span></a>和<a class="reference internal" href="#doctest-simple-testfile"><span>Simple Usage: Checking Examples in a Text File</span></a>部分。</span></p><dl class="function"><dt id="doctest.testfile"><span class="yiyi-st" id="yiyi-236"> <code class="descclassname">doctest.</code><code class="descname">testfile</code><span class="sig-paren">(</span><em>filename</em>, <em>module_relative=True</em>, <em>name=None</em>, <em>package=None</em>, <em>globs=None</em>, <em>verbose=None</em>, <em>report=True</em>, <em>optionflags=0</em>, <em>extraglobs=None</em>, <em>raise_on_error=False</em>, <em>parser=DocTestParser()</em>, <em>encoding=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-237">除<em>文件名</em>以外的所有参数都是可选的,并应以关键字形式指定。</span></p><p><span class="yiyi-st" id="yiyi-238">名为<em>文件名</em>的文件中的测试示例。</span><span class="yiyi-st" id="yiyi-239">返回<code class="docutils literal"><span class="pre">(failure_count,</span> <span class="pre">test_count)</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-240">可选参数<em>module_relative</em>指定如何解释文件名:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-241">如果<em>module_relative</em>为<code class="docutils literal"><span class="pre">True</span></code>(缺省值),那么<em>filename</em>指定一个与操作系统无关的模块相对路径。</span><span class="yiyi-st" id="yiyi-242">默认情况下,这个路径是相对于调用模块的目录;但是如果指定了<em>package</em>参数,那么它是相对于该包的。</span><span class="yiyi-st" id="yiyi-243">To ensure OS-independence, <em>filename</em> should use <code class="docutils literal"><span class="pre">/</span></code> characters to separate path segments, and may not be an absolute path (i.e., it may not begin with <code class="docutils literal"><span class="pre">/</span></code>).</span></li><li><span class="yiyi-st" id="yiyi-244">如果<em>module_relative</em>为<code class="docutils literal"><span class="pre">False</span></code>,则<em>filename</em>指定一个OS特定的路径。</span><span class="yiyi-st" id="yiyi-245">路径可以是绝对的或相对的;相对路径相对于当前工作目录被解析。</span></li></ul><p><span class="yiyi-st" id="yiyi-246">可选参数<em>name</em>给出测试的名称;默认情况下,或者使用<code class="docutils literal"><span class="pre">None</span></code>,<code class="docutils literal"><span class="pre">os.path.basename(filename)</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-247">可选参数<em>package</em>是Python包或Python包的名称,其目录应作为模块相关文件名的基本目录。</span><span class="yiyi-st" id="yiyi-248">如果未指定包,则调用模块的目录将用作模块相关文件名的基本目录。</span><span class="yiyi-st" id="yiyi-249">如果<em>module_relative</em>为<code class="docutils literal"><span class="pre">False</span></code>,则指定<em>package</em>是错误的。</span></p><p><span class="yiyi-st" id="yiyi-250">可选参数<em>globs</em>在执行示例时给出了一个用作全局变量的词典。</span><span class="yiyi-st" id="yiyi-251">这个词典的一个新的浅拷贝是为doctest创建的,所以它的例子从一个干净的石板开始。</span><span class="yiyi-st" id="yiyi-252">默认情况下,或者如果<code class="docutils literal"><span class="pre">None</span></code>,则使用新的空字典。</span></p><p><span class="yiyi-st" id="yiyi-253">可选参数<em>extraglobs</em>给出了一个合并到用于执行示例的全局变量中的字典。</span><span class="yiyi-st" id="yiyi-254">这可以像<a class="reference internal" href="stdtypes.html#dict.update" title="dict.update"><code class="xref py py-meth docutils literal"><span class="pre">dict.update()</span></code></a>一样工作:if <em>globs</em>和<em>extraglobs</em>具有共同的关键字,<em>extraglobs t5 >出现在组合字典中。</em></span><span class="yiyi-st" id="yiyi-255">默认情况下,或者<code class="docutils literal"><span class="pre">None</span></code>,不使用额外的全局变量。</span><span class="yiyi-st" id="yiyi-256">这是一个允许doctests参数化的高级功能。</span><span class="yiyi-st" id="yiyi-257">例如,可以为基类编写一个doctest,使用该类的通用名称,然后通过传递将通用名称映射到子类的<em>extraglobs</em>字典来重新测试任意数量的子类测试。</span></p><p><span class="yiyi-st" id="yiyi-258">可选参数<em>verbose</em>如果为true,则会输出大量内容,如果为false,则只打印失败;默认情况下,或者如果<code class="docutils literal"><span class="pre">None</span></code>,当且仅当<code class="docutils literal"><span class="pre">'-v'</span></code>位于<code class="docutils literal"><span class="pre">sys.argv</span></code>中时才为true。</span></p><p><span class="yiyi-st" id="yiyi-259">可选参数<em>报告</em>在最后打印摘要时为true,否则在最后不打印任何内容。</span><span class="yiyi-st" id="yiyi-260">在详细模式下,摘要是详细的,否则摘要非常简短(实际上,如果所有测试都通过,则为空)。</span></p><p><span class="yiyi-st" id="yiyi-261">可选参数<em>optionflags</em>(默认值0)采用按位或选项标志。</span><span class="yiyi-st" id="yiyi-262">请参阅<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span></p><p><span class="yiyi-st" id="yiyi-263">可选参数<em>raise_on_error</em>默认为false。</span><span class="yiyi-st" id="yiyi-264">如果为true,则在例子中发生第一次失败或意外异常时引发异常。</span><span class="yiyi-st" id="yiyi-265">这样可以对故障进行事后调试。</span><span class="yiyi-st" id="yiyi-266">默认行为是继续运行示例。</span></p><p><span class="yiyi-st" id="yiyi-267">Optional argument <em>parser</em> specifies a <a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a> (or subclass) that should be used to extract tests from the files. </span><span class="yiyi-st" id="yiyi-268">It defaults to a normal parser (i.e., <code class="docutils literal"><span class="pre">DocTestParser()</span></code>).</span></p><p><span class="yiyi-st" id="yiyi-269">可选参数<em>编码</em>指定应该用于将文件转换为unicode的编码。</span></p></dd></dl><dl class="function"><dt id="doctest.testmod"><span class="yiyi-st" id="yiyi-270"> <code class="descclassname">doctest.</code><code class="descname">testmod</code><span class="sig-paren">(</span><em>m=None</em>, <em>name=None</em>, <em>globs=None</em>, <em>verbose=None</em>, <em>report=True</em>, <em>optionflags=0</em>, <em>extraglobs=None</em>, <em>raise_on_error=False</em>, <em>exclude_empty=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-271">所有参数都是可选的,除<em>m</em>以外的所有参数均应以关键字形式指定。</span></p><p><span class="yiyi-st" id="yiyi-272">如果没有提供<em>m</em>或者<em><em></em>,则可以从模块<em>m</em>(或模块<a class="reference internal" href="__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal"><span class="pre">__main__</span></code></a>)访问的函数和类的docstrings中的测试示例< t5>),从<code class="docutils literal"><span class="pre">m.__doc__</span></code>开始。</em></span></p><p><span class="yiyi-st" id="yiyi-273">还有可以从dict <code class="docutils literal"><span class="pre">m.__test__</span></code>到达的测试示例,如果它存在并且不是<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-274"><code class="docutils literal"><span class="pre">m.__test__</span></code> maps names (strings) to functions, classes and strings; function and class docstrings are searched for examples; strings are searched directly, as if they were docstrings.</span></p><p><span class="yiyi-st" id="yiyi-275">仅搜索附加到属于模块<em>m</em>的对象的文档字符串。</span></p><p><span class="yiyi-st" id="yiyi-276">返回<code class="docutils literal"><span class="pre">(failure_count,</span> <span class="pre">test_count)</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-277">可选参数<em>name</em>给出模块的名称;默认情况下,或者使用<code class="docutils literal"><span class="pre">None</span></code>,<code class="docutils literal"><span class="pre">m.__name__</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-278">可选参数<em>exclude_empty</em>默认为false。</span><span class="yiyi-st" id="yiyi-279">如果属实,则没有找到doctests的对象将被排除在考虑之外。</span><span class="yiyi-st" id="yiyi-280">缺省值是向后兼容性hack,因此仍然使用<code class="xref py py-meth docutils literal"><span class="pre">doctest.master.summarize()</span></code>与<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>结合使用的代码可以继续为没有测试的对象获取输出。</span><span class="yiyi-st" id="yiyi-281">更新的<a class="reference internal" href="#doctest.DocTestFinder" title="doctest.DocTestFinder"><code class="xref py py-class docutils literal"><span class="pre">DocTestFinder</span></code></a>构造函数的<em>exclude_empty</em>参数默认为true。</span></p><p><span class="yiyi-st" id="yiyi-282">可选参数<em>extraglobs</em>,<em>verbose</em>,<em>report</em>,<em>optionflags</em>,<em>raise_on_error</em>和<em> globs与上面的函数<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>相同,但<em>globs</em>默认为<code class="docutils literal"><span class="pre">m.__dict__</span></code>。</em></span></p></dd></dl><dl class="function"><dt id="doctest.run_docstring_examples"><span class="yiyi-st" id="yiyi-283"> <code class="descclassname">doctest.</code><code class="descname">run_docstring_examples</code><span class="sig-paren">(</span><em>f</em>, <em>globs</em>, <em>verbose=False</em>, <em>name="NoName"</em>, <em>compileflags=None</em>, <em>optionflags=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-284">与对象<em>f</em>关联的测试示例;例如,<em>f</em>可以是字符串,模块,函数或类对象。</span></p><p><span class="yiyi-st" id="yiyi-285">字典参数<em>globs</em>的浅拷贝用于执行上下文。</span></p><p><span class="yiyi-st" id="yiyi-286">可选参数<em>name</em>用于失败消息中,并且缺省为<code class="docutils literal"><span class="pre">"NoName"</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-287">如果可选参数<em>verbose</em>为true,则即使没有故障,也会生成输出。</span><span class="yiyi-st" id="yiyi-288">默认情况下,仅在发生示例故障时才会生成输出。</span></p><p><span class="yiyi-st" id="yiyi-289">可选参数<em>compileflags</em>给出了运行示例时Python编译器应该使用的一组标志。</span><span class="yiyi-st" id="yiyi-290">默认情况下,或者<code class="docutils literal"><span class="pre">None</span></code>,将根据<em>globs</em>中找到的未来特征集推导出标志。</span></p><p><span class="yiyi-st" id="yiyi-291">可选参数<em>optionflags</em>的作用与上面的函数<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>相同。</span></p></dd></dl></div><div class="section" id="unittest-api"><h2><span class="yiyi-st" id="yiyi-292">26.3.5. </span><span class="yiyi-st" id="yiyi-293">Unittest API </span></h2><p><span class="yiyi-st" id="yiyi-294">随着您的文档测试模块集合的增长,您需要一种系统地运行所有文档测试的方法。</span><span class="yiyi-st" id="yiyi-295"><a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> provides two functions that can be used to create <a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a> test suites from modules and text files containing doctests. </span><span class="yiyi-st" id="yiyi-296">要与<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>测试发现集成,请在您的测试模块中包含一个<code class="xref py py-func docutils literal"><span class="pre">load_tests()</span></code>函数:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">unittest</span>
|
||
<span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="kn">import</span> <span class="nn">my_module_with_doctests</span>
|
||
|
||
<span class="k">def</span> <span class="nf">load_tests</span><span class="p">(</span><span class="n">loader</span><span class="p">,</span> <span class="n">tests</span><span class="p">,</span> <span class="n">ignore</span><span class="p">):</span>
|
||
<span class="n">tests</span><span class="o">.</span><span class="n">addTests</span><span class="p">(</span><span class="n">doctest</span><span class="o">.</span><span class="n">DocTestSuite</span><span class="p">(</span><span class="n">my_module_with_doctests</span><span class="p">))</span>
|
||
<span class="k">return</span> <span class="n">tests</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-297">有两个主要的功能用于从具有doctests的文本文件和模块创建<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>实例:</span></p><dl class="function"><dt id="doctest.DocFileSuite"><span class="yiyi-st" id="yiyi-298"> <code class="descclassname">doctest.</code><code class="descname">DocFileSuite</code><span class="sig-paren">(</span><em>*paths</em>, <em>module_relative=True</em>, <em>package=None</em>, <em>setUp=None</em>, <em>tearDown=None</em>, <em>globs=None</em>, <em>optionflags=0</em>, <em>parser=DocTestParser()</em>, <em>encoding=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-299">将doctest测试从一个或多个文本文件转换为<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-300">返回的<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>将由unittest框架运行,并在每个文件中运行交互式示例。</span><span class="yiyi-st" id="yiyi-301">如果任何文件中的示例失败,则合成的单元测试失败,并引发<code class="xref py py-exc docutils literal"><span class="pre">failureException</span></code>异常,显示包含测试的文件的名称和一个(有时是近似的)行号。</span></p><p><span class="yiyi-st" id="yiyi-302">将一个或多个路径(字符串)传递给要检查的文本文件。</span></p><p><span class="yiyi-st" id="yiyi-303">选项可以作为关键字参数提供:</span></p><p><span class="yiyi-st" id="yiyi-304">可选参数<em>module_relative</em>指定应如何解释<em>路径</em>中的文件名:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-305">如果<em>module_relative</em>为<code class="docutils literal"><span class="pre">True</span></code>(缺省值),那么<em>paths</em>中的每个文件名指定一个独立于操作系统的模块相对路径。</span><span class="yiyi-st" id="yiyi-306">默认情况下,这个路径是相对于调用模块的目录;但是如果指定了<em>package</em>参数,那么它是相对于该包的。</span><span class="yiyi-st" id="yiyi-307">为了确保OS独立性,每个文件名应该使用<code class="docutils literal"><span class="pre">/</span></code>个字符来分隔路径段,并且可能不是绝对路径(即它可能不以<code class="docutils literal"><span class="pre">/</span></code>开头)。</span></li><li><span class="yiyi-st" id="yiyi-308">如果<em>module_relative</em>是<code class="docutils literal"><span class="pre">False</span></code>,那么<em>路径中的每个文件名都指定了特定于操作系统的路径。</em></span><span class="yiyi-st" id="yiyi-309">路径可以是绝对的或相对的;相对路径相对于当前工作目录被解析。</span></li></ul><p><span class="yiyi-st" id="yiyi-310">可选参数<em>package</em>是一个Python包或一个Python包的名称,其目录应该用作<em>路径</em>中与模块相关的文件名的基本目录。</span><span class="yiyi-st" id="yiyi-311">如果未指定包,则调用模块的目录将用作模块相关文件名的基本目录。</span><span class="yiyi-st" id="yiyi-312">如果<em>module_relative</em>为<code class="docutils literal"><span class="pre">False</span></code>,则指定<em>package</em>是错误的。</span></p><p><span class="yiyi-st" id="yiyi-313">可选参数<em>setUp</em>指定测试套件的设置函数。</span><span class="yiyi-st" id="yiyi-314">这在每个文件中运行测试之前被调用。</span><span class="yiyi-st" id="yiyi-315">The <em>setUp</em> function will be passed a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> object. </span><span class="yiyi-st" id="yiyi-316">setUp函数可以通过测试的<em>globs</em>属性来访问测试全局变量。</span></p><p><span class="yiyi-st" id="yiyi-317">可选参数<em>tearDown</em>指定测试套件的拆卸函数。</span><span class="yiyi-st" id="yiyi-318">这是在每个文件中运行测试后调用的。</span><span class="yiyi-st" id="yiyi-319">The <em>tearDown</em> function will be passed a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> object. </span><span class="yiyi-st" id="yiyi-320">setUp函数可以通过测试的<em>globs</em>属性来访问测试全局变量。</span></p><p><span class="yiyi-st" id="yiyi-321">可选参数<em>globs</em>是包含测试初始全局变量的字典。</span><span class="yiyi-st" id="yiyi-322">每个测试都会创建一本新字典。</span><span class="yiyi-st" id="yiyi-323">默认情况下,<em>globs</em>是一个新的空字典。</span></p><p><span class="yiyi-st" id="yiyi-324">可选参数<em>optionflags</em>指定由各个选项标志创建或组合在一起的测试的默认doctest选项。</span><span class="yiyi-st" id="yiyi-325">请参阅<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span><span class="yiyi-st" id="yiyi-326">请参阅下面的函数<a class="reference internal" href="#doctest.set_unittest_reportflags" title="doctest.set_unittest_reportflags"><code class="xref py py-func docutils literal"><span class="pre">set_unittest_reportflags()</span></code></a>以更好地设置报告选项。</span></p><p><span class="yiyi-st" id="yiyi-327">Optional argument <em>parser</em> specifies a <a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a> (or subclass) that should be used to extract tests from the files. </span><span class="yiyi-st" id="yiyi-328">It defaults to a normal parser (i.e., <code class="docutils literal"><span class="pre">DocTestParser()</span></code>).</span></p><p><span class="yiyi-st" id="yiyi-329">可选参数<em>编码</em>指定应该用于将文件转换为unicode的编码。</span></p><p><span class="yiyi-st" id="yiyi-330">使用<a class="reference internal" href="#doctest.DocFileSuite" title="doctest.DocFileSuite"><code class="xref py py-func docutils literal"><span class="pre">DocFileSuite()</span></code></a>将全局<code class="docutils literal"><span class="pre">__file__</span></code>添加到提供给从文本文件加载的文档测试的全局变量中。</span></p></dd></dl><dl class="function"><dt id="doctest.DocTestSuite"><span class="yiyi-st" id="yiyi-331"> <code class="descclassname">doctest.</code><code class="descname">DocTestSuite</code><span class="sig-paren">(</span><em>module=None</em>, <em>globs=None</em>, <em>extraglobs=None</em>, <em>test_finder=None</em>, <em>setUp=None</em>, <em>tearDown=None</em>, <em>checker=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-332">将模块的doctest测试转换为<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-333">返回的<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>将由unittest框架运行,并在模块中运行每个doctest。</span><span class="yiyi-st" id="yiyi-334">如果任何文档测试失败,则合成的单元测试失败,并引发<code class="xref py py-exc docutils literal"><span class="pre">failureException</span></code>异常,显示包含测试的文件的名称和一个(有时是近似的)行号。</span></p><p><span class="yiyi-st" id="yiyi-335">可选自变量<em>模块</em>提供要测试的模块。</span><span class="yiyi-st" id="yiyi-336">它可以是一个模块对象或一个(可能点缀的)模块名称。</span><span class="yiyi-st" id="yiyi-337">如果未指定,则使用调用此函数的模块。</span></p><p><span class="yiyi-st" id="yiyi-338">可选参数<em>globs</em>是包含测试初始全局变量的字典。</span><span class="yiyi-st" id="yiyi-339">每个测试都会创建一本新字典。</span><span class="yiyi-st" id="yiyi-340">默认情况下,<em>globs</em>是一个新的空字典。</span></p><p><span class="yiyi-st" id="yiyi-341">可选参数<em>extraglobs</em>指定了一组额外的全局变量,它们被合并到<em>globs</em>中。</span><span class="yiyi-st" id="yiyi-342">默认情况下,不使用额外的全局变量。</span></p><p><span class="yiyi-st" id="yiyi-343">可选参数<em>test_finder</em>是用于从模块中提取doctests的<a class="reference internal" href="#doctest.DocTestFinder" title="doctest.DocTestFinder"><code class="xref py py-class docutils literal"><span class="pre">DocTestFinder</span></code></a>对象(或嵌入式替换)。</span></p><p><span class="yiyi-st" id="yiyi-344">可选参数<em>setUp</em>,<em>tearDown</em>和<em>optionflags</em>与上面的函数<a class="reference internal" href="#doctest.DocFileSuite" title="doctest.DocFileSuite"><code class="xref py py-func docutils literal"><span class="pre">DocFileSuite()</span></code></a>相同。</span></p><p><span class="yiyi-st" id="yiyi-345">该函数使用与<a class="reference internal" href="#doctest.testmod" title="doctest.testmod"><code class="xref py py-func docutils literal"><span class="pre">testmod()</span></code></a>相同的搜索技术。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-346"><span class="versionmodified">Changed in version 3.5: </span><a class="reference internal" href="#doctest.DocTestSuite" title="doctest.DocTestSuite"><code class="xref py py-func docutils literal"><span class="pre">DocTestSuite()</span></code></a> returns an empty <a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a> if <em>module</em> contains no docstrings instead of raising <a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>.</span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-347">Under the covers, <a class="reference internal" href="#doctest.DocTestSuite" title="doctest.DocTestSuite"><code class="xref py py-func docutils literal"><span class="pre">DocTestSuite()</span></code></a> creates a <a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a> out of <code class="xref py py-class docutils literal"><span class="pre">doctest.DocTestCase</span></code> instances, and <code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code> is a subclass of <a class="reference internal" href="unittest.html#unittest.TestCase" title="unittest.TestCase"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestCase</span></code></a>. </span><span class="yiyi-st" id="yiyi-348"><code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code> isn’t documented here (it’s an internal detail), but studying its code can answer questions about the exact details of <a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a> integration.</span></p><p><span class="yiyi-st" id="yiyi-349">Similarly, <a class="reference internal" href="#doctest.DocFileSuite" title="doctest.DocFileSuite"><code class="xref py py-func docutils literal"><span class="pre">DocFileSuite()</span></code></a> creates a <a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a> out of <code class="xref py py-class docutils literal"><span class="pre">doctest.DocFileCase</span></code> instances, and <code class="xref py py-class docutils literal"><span class="pre">DocFileCase</span></code> is a subclass of <code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-350">因此创建<a class="reference internal" href="unittest.html#unittest.TestSuite" title="unittest.TestSuite"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestSuite</span></code></a>的两种方式都运行<code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code>的实例。</span><span class="yiyi-st" id="yiyi-351">This is important for a subtle reason: when you run <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> functions yourself, you can control the <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> options in use directly, by passing option flags to <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> functions. </span><span class="yiyi-st" id="yiyi-352">但是,如果您正在编写一个<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>框架,<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>最终将控制何时以及如何运行测试。</span><span class="yiyi-st" id="yiyi-353">框架作者通常希望控制<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>报告选项(可能例如通过命令行选项指定),但是没有办法将选项通过<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>传递给<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a></span></p><p><span class="yiyi-st" id="yiyi-354">For this reason, <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> also supports a notion of <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> reporting flags specific to <a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a> support, via this function:</span></p><dl class="function"><dt id="doctest.set_unittest_reportflags"><span class="yiyi-st" id="yiyi-355"><code class="descclassname">文档测试 T0> <code class="descname"> set_unittest_reportflags T1> <span class="sig-paren">( T2> <em>标志 T3> <span class="sig-paren">) T4> </span></em></span></code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-356">设置要使用的<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>报告标志。</span></p><p><span class="yiyi-st" id="yiyi-357">参数<em>标志</em>采用按位或选项标志。</span><span class="yiyi-st" id="yiyi-358">请参阅<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span><span class="yiyi-st" id="yiyi-359">只能使用“报告标志”。</span></p><p><span class="yiyi-st" id="yiyi-360">这是一个模块全局设置,并影响模块<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>运行的所有未来文档测试:<code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code>的<code class="xref py py-meth docutils literal"><span class="pre">runTest()</span></code>方法查看选项在构造<code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code>实例时为测试用例指定的标志。</span><span class="yiyi-st" id="yiyi-361">If no reporting flags were specified (which is the typical and expected case), <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>‘s <a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a> reporting flags are or’ed into the option flags, and the option flags so augmented are passed to the <a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a> instance created to run the doctest. </span><span class="yiyi-st" id="yiyi-362">如果在构造<code class="xref py py-class docutils literal"><span class="pre">DocTestCase</span></code>实例时指定了任何报告标志,则忽略<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>的<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>报告标志。</span></p><p><span class="yiyi-st" id="yiyi-363">在函数调用之前有效的<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>报告标志的值由函数返回。</span></p></dd></dl></div><div class="section" id="advanced-api"><h2><span class="yiyi-st" id="yiyi-364">26.3.6. </span><span class="yiyi-st" id="yiyi-365">高级API </span></h2><p><span class="yiyi-st" id="yiyi-366">基本的API是一个简单的包装,旨在使doctest易于使用。</span><span class="yiyi-st" id="yiyi-367">它相当灵活,应该满足大多数用户的需求;但是,如果您需要对测试进行更精细的控制,或者希望扩展doctest的功能,那么您应该使用高级API。</span></p><p><span class="yiyi-st" id="yiyi-368">高级API围绕两个容器类进行,这两个容器类用于存储从doctest案例中提取的交互式示例:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-369"><a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>:一个Python <a class="reference internal" href="../glossary.html#term-statement"><span class="xref std std-term">statement</span></a>,与它的预期输出配对。</span></li><li><span class="yiyi-st" id="yiyi-370"><a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>: A collection of <a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>s, typically extracted from a single docstring or text file.</span></li></ul><p><span class="yiyi-st" id="yiyi-371">定义其他处理类来查找,分析和运行,并检查doctest示例:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-372"><a class="reference internal" href="#doctest.DocTestFinder" title="doctest.DocTestFinder"><code class="xref py py-class docutils literal"><span class="pre">DocTestFinder</span></code></a>: Finds all docstrings in a given module, and uses a <a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a> to create a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> from every docstring that contains interactive examples.</span></li><li><span class="yiyi-st" id="yiyi-373"><a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a>: Creates a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> object from a string (such as an object’s docstring).</span></li><li><span class="yiyi-st" id="yiyi-374"><a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>: Executes the examples in a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>, and uses an <a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a> to verify their output.</span></li><li><span class="yiyi-st" id="yiyi-375"><a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>:将doctest示例的实际输出与预期输出进行比较,并确定它们是否匹配。</span></li></ul><p><span class="yiyi-st" id="yiyi-376">下图总结了这些处理类之间的关系:</span></p><pre><code class="language-python"><span></span> <span class="nb">list</span> <span class="n">of</span><span class="p">:</span>
|
||
<span class="o">+------+</span> <span class="o">+---------+</span>
|
||
<span class="o">|</span><span class="n">module</span><span class="o">|</span> <span class="o">--</span><span class="n">DocTestFinder</span><span class="o">-></span> <span class="o">|</span> <span class="n">DocTest</span> <span class="o">|</span> <span class="o">--</span><span class="n">DocTestRunner</span><span class="o">-></span> <span class="n">results</span>
|
||
<span class="o">+------+</span> <span class="o">|</span> <span class="o">^</span> <span class="o">+---------+</span> <span class="o">|</span> <span class="o">^</span> <span class="p">(</span><span class="n">printed</span><span class="p">)</span>
|
||
<span class="o">|</span> <span class="o">|</span> <span class="o">|</span> <span class="n">Example</span> <span class="o">|</span> <span class="o">|</span> <span class="o">|</span>
|
||
<span class="n">v</span> <span class="o">|</span> <span class="o">|</span> <span class="o">...</span> <span class="o">|</span> <span class="n">v</span> <span class="o">|</span>
|
||
<span class="n">DocTestParser</span> <span class="o">|</span> <span class="n">Example</span> <span class="o">|</span> <span class="n">OutputChecker</span>
|
||
<span class="o">+---------+</span>
|
||
</code></pre><div class="section" id="doctest-objects"><h3><span class="yiyi-st" id="yiyi-377">26.3.6.1. </span><span class="yiyi-st" id="yiyi-378">DocTest Objects </span></h3><dl class="class"><dt id="doctest.DocTest"><span class="yiyi-st" id="yiyi-379"> <em class="property">class </em><code class="descclassname">doctest.</code><code class="descname">DocTest</code><span class="sig-paren">(</span><em>examples</em>, <em>globs</em>, <em>name</em>, <em>filename</em>, <em>lineno</em>, <em>docstring</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-380">应该在单个命名空间中运行的doctest示例的集合。</span><span class="yiyi-st" id="yiyi-381">构造函数参数用于初始化相同名称的属性。</span></p><p><span class="yiyi-st" id="yiyi-382"><a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> defines the following attributes. </span><span class="yiyi-st" id="yiyi-383">它们由构造函数初始化,不应该直接修改。</span></p><dl class="attribute"><dt id="doctest.DocTest.examples"><span class="yiyi-st" id="yiyi-384"><code class="descname">实施例 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-385"><a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>对象的列表,用于编码应该由此测试运行的各个交互式Python示例。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTest.globs"><span class="yiyi-st" id="yiyi-386"><code class="descname">水珠 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-387">应该运行示例的名称空间(又称全局变量)。</span><span class="yiyi-st" id="yiyi-388">这是一个将名字映射到值的字典。</span><span class="yiyi-st" id="yiyi-389">测试运行后,示例所做的对名称空间的任何更改(例如绑定新变量)都会反映在<a class="reference internal" href="#doctest.DocTest.globs" title="doctest.DocTest.globs"><code class="xref py py-attr docutils literal"><span class="pre">globs</span></code></a>中。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTest.name"><span class="yiyi-st" id="yiyi-390"><code class="descname">名称 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-391">A string name identifying the <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>. </span><span class="yiyi-st" id="yiyi-392">通常,这是测试从中提取的对象或文件的名称。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTest.filename"><span class="yiyi-st" id="yiyi-393"><code class="descname">文件名 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-394">该<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>从中提取的文件的名称;或<code class="docutils literal"><span class="pre">None</span></code>,如果文件名未知,或者<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>未从文件中提取。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTest.lineno"><span class="yiyi-st" id="yiyi-395"><code class="descname"> LINENO T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-396"><a class="reference internal" href="#doctest.DocTest.filename" title="doctest.DocTest.filename"><code class="xref py py-attr docutils literal"><span class="pre">filename</span></code></a>中的行号,其中<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>开头;如果行号不可用,则为<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-397">该行号相对于文件的开头是从零开始的。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTest.docstring"><span class="yiyi-st" id="yiyi-398"><code class="descname">文档字符串 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-399">提取测试的字符串,如果字符串不可用,或者测试未从字符串中提取,则返回“无”。</span></p></dd></dl></dd></dl></div><div class="section" id="example-objects"><h3><span class="yiyi-st" id="yiyi-400">26.3.6.2. </span><span class="yiyi-st" id="yiyi-401">示例对象</span></h3><dl class="class"><dt id="doctest.Example"><span class="yiyi-st" id="yiyi-402"> <em class="property">class </em><code class="descclassname">doctest.</code><code class="descname">Example</code><span class="sig-paren">(</span><em>source</em>, <em>want</em>, <em>exc_msg=None</em>, <em>lineno=0</em>, <em>indent=0</em>, <em>options=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-403">一个交互式示例,由Python语句及其预期输出组成。</span><span class="yiyi-st" id="yiyi-404">构造函数参数用于初始化相同名称的属性。</span></p><p><span class="yiyi-st" id="yiyi-405"><a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>定义了以下属性。</span><span class="yiyi-st" id="yiyi-406">它们由构造函数初始化,不应该直接修改。</span></p><dl class="attribute"><dt id="doctest.Example.source"><span class="yiyi-st" id="yiyi-407"><code class="descname">源 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-408">包含示例源代码的字符串。</span><span class="yiyi-st" id="yiyi-409">这个源代码由一个Python语句组成,并且总是以换行符结尾;构造函数在必要时添加一个换行符。</span></p></dd></dl><dl class="attribute"><dt id="doctest.Example.want"><span class="yiyi-st" id="yiyi-410"><code class="descname">想 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-411">运行示例源代码的预期输出(来自标准输出,或者异常情况下的回溯)。</span><span class="yiyi-st" id="yiyi-412">除非预计没有输出,否则<a class="reference internal" href="#doctest.Example.want" title="doctest.Example.want"><code class="xref py py-attr docutils literal"><span class="pre">want</span></code></a>以换行符结束,在这种情况下,它是一个空字符串。</span><span class="yiyi-st" id="yiyi-413">构造函数在必要时添加一个换行符。</span></p></dd></dl><dl class="attribute"><dt id="doctest.Example.exc_msg"><span class="yiyi-st" id="yiyi-414"><code class="descname"> exc_msg T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-415">该示例生成的异常消息,如果该示例预计会生成异常;或<code class="docutils literal"><span class="pre">None</span></code>,如果不希望产生异常。</span><span class="yiyi-st" id="yiyi-416">该异常消息将与<a class="reference internal" href="traceback.html#traceback.format_exception_only" title="traceback.format_exception_only"><code class="xref py py-func docutils literal"><span class="pre">traceback.format_exception_only()</span></code></a>的返回值进行比较。</span><span class="yiyi-st" id="yiyi-417"><a class="reference internal" href="#doctest.Example.exc_msg" title="doctest.Example.exc_msg"><code class="xref py py-attr docutils literal"><span class="pre">exc_msg</span></code></a>以换行符结束,除非它<code class="docutils literal"><span class="pre">None</span></code>。</span><span class="yiyi-st" id="yiyi-418">如果需要,构造函数会添加一个换行符。</span></p></dd></dl><dl class="attribute"><dt id="doctest.Example.lineno"><span class="yiyi-st" id="yiyi-419"><code class="descname"> LINENO T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-420">包含示例开始处的示例的字符串中的行号。</span><span class="yiyi-st" id="yiyi-421">该行号相对于包含字符串的开头是从零开始的。</span></p></dd></dl><dl class="attribute"><dt id="doctest.Example.indent"><span class="yiyi-st" id="yiyi-422"><code class="descname">缩进 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-423">包含字符串中的示例缩进,即示例第一个提示之前的空格字符数。</span></p></dd></dl><dl class="attribute"><dt id="doctest.Example.options"><span class="yiyi-st" id="yiyi-424"><code class="descname">选项 T0> </code></span></dt><dd><p><span class="yiyi-st" id="yiyi-425">从选项标记到<code class="docutils literal"><span class="pre">True</span></code>或<code class="docutils literal"><span class="pre">False</span></code>的字典映射,用于覆盖此示例的默认选项。</span><span class="yiyi-st" id="yiyi-426">这个字典中没有包含的任何选项标记都保留默认值(由<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的<code class="xref py py-attr docutils literal"><span class="pre">optionflags</span></code>指定)。</span><span class="yiyi-st" id="yiyi-427">默认情况下,不设置任何选项。</span></p></dd></dl></dd></dl></div><div class="section" id="doctestfinder-objects"><h3><span class="yiyi-st" id="yiyi-428">26.3.6.3. </span><span class="yiyi-st" id="yiyi-429">DocTestFinder对象</span></h3><dl class="class"><dt id="doctest.DocTestFinder"><span class="yiyi-st" id="yiyi-430"> <em class="property">class </em><code class="descclassname">doctest.</code><code class="descname">DocTestFinder</code><span class="sig-paren">(</span><em>verbose=False</em>, <em>parser=DocTestParser()</em>, <em>recurse=True</em>, <em>exclude_empty=True</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-431">一个处理类,用于从文档字符串及其包含对象的文档字符串中提取与给定对象相关的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>。</span><span class="yiyi-st" id="yiyi-432"><a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>s can be extracted from modules, classes, functions, methods, staticmethods, classmethods, and properties.</span></p><p><span class="yiyi-st" id="yiyi-433">可选参数<em>verbose</em>可用于显示查找器搜索的对象。</span><span class="yiyi-st" id="yiyi-434">它默认为<code class="docutils literal"><span class="pre">False</span></code>(无输出)。</span></p><p><span class="yiyi-st" id="yiyi-435">可选参数<em>分析器</em>指定用于从文档字符串中提取文档测试的<a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a>对象(或插入替换)。</span></p><p><span class="yiyi-st" id="yiyi-436">如果可选参数<em>recurse</em>为false,则<a class="reference internal" href="#doctest.DocTestFinder.find" title="doctest.DocTestFinder.find"><code class="xref py py-meth docutils literal"><span class="pre">DocTestFinder.find()</span></code></a>将仅检查给定对象,而不检查包含的任何对象。</span></p><p><span class="yiyi-st" id="yiyi-437">如果可选参数<em>exclude_empty</em>为false,则<a class="reference internal" href="#doctest.DocTestFinder.find" title="doctest.DocTestFinder.find"><code class="xref py py-meth docutils literal"><span class="pre">DocTestFinder.find()</span></code></a>将包含具有空文档字符串的对象的测试。</span></p><p><span class="yiyi-st" id="yiyi-438"><a class="reference internal" href="#doctest.DocTestFinder" title="doctest.DocTestFinder"><code class="xref py py-class docutils literal"><span class="pre">DocTestFinder</span></code></a> defines the following method:</span></p><dl class="method"><dt id="doctest.DocTestFinder.find"><span class="yiyi-st" id="yiyi-439"> <code class="descname">find</code><span class="sig-paren">(</span><em>obj[, name][, module][, globs][, extraglobs]</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-440">返回由<em>obj</em>的文档字符串或其包含的任何对象的文档字符串定义的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>的列表。</span></p><p><span class="yiyi-st" id="yiyi-441">可选参数<em>name</em>指定对象的名称;此名称将用于为返回的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>构造名称。如果未指定<em>name</em>,则使用<code class="docutils literal"><span class="pre">obj.__name__</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-442">可选参数<em>module</em>是包含给定对象的模块。</span><span class="yiyi-st" id="yiyi-443">如果该模块没有被指定或是无,则测试发现者将尝试自动确定正确的模块。</span><span class="yiyi-st" id="yiyi-444">使用该对象的模块:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-445">作为默认命名空间,如果未指定<em>globs</em>。</span></li><li><span class="yiyi-st" id="yiyi-446">阻止DocTestFinder从其他模块导入的对象中提取DocTests。</span><span class="yiyi-st" id="yiyi-447">(包含<em>module</em>以外的模块的包含对象将被忽略。)</span></li><li><span class="yiyi-st" id="yiyi-448">查找包含该对象的文件的名称。</span></li><li><span class="yiyi-st" id="yiyi-449">帮助查找文件中对象的行号。</span></li></ul><p><span class="yiyi-st" id="yiyi-450">如果<em>module</em>为<code class="docutils literal"><span class="pre">False</span></code>,则不会尝试查找模块。</span><span class="yiyi-st" id="yiyi-451">这很难理解,主要用于测试doctest自身:如果<em>module</em>是<code class="docutils literal"><span class="pre">False</span></code>,或者<code class="docutils literal"><span class="pre">None</span></code>但不能自动找到,则所有对象被认为属于(不存在的)模块,因此所有包含的对象将(递归地)搜索doctests。</span></p><p><span class="yiyi-st" id="yiyi-452">The globals for each <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a> is formed by combining <em>globs</em> and <em>extraglobs</em> (bindings in <em>extraglobs</em> override bindings in <em>globs</em>). </span><span class="yiyi-st" id="yiyi-453">为每个<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>创建一个新的globals字典的浅表副本。</span><span class="yiyi-st" id="yiyi-454">如果未指定<em>globs</em>,则默认为模块的<em>__ dict __</em>,否则为<code class="docutils literal"><span class="pre">{}</span></code>。</span><span class="yiyi-st" id="yiyi-455">如果未指定<em>extraglobs</em>,则默认为<code class="docutils literal"><span class="pre">{}</span></code>。</span></p></dd></dl></dd></dl></div><div class="section" id="doctestparser-objects"><h3><span class="yiyi-st" id="yiyi-456">26.3.6.4. </span><span class="yiyi-st" id="yiyi-457">DocTestParser对象</span></h3><dl class="class"><dt id="doctest.DocTestParser"><span class="yiyi-st" id="yiyi-458"><em class="property">class</em> <code class="descclassname">doctest。</code> <code class="descname">DocTestParser</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-459">处理类,用于从字符串中提取交互式示例,并使用它们创建<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象。</span></p><p><span class="yiyi-st" id="yiyi-460"><a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a> defines the following methods:</span></p><dl class="method"><dt id="doctest.DocTestParser.get_doctest"><span class="yiyi-st" id="yiyi-461"><code class="descname">get_doctest</code> <span class="sig-paren">(</span> <em>string</em>,<em>globs</em>,<em>name</em>,<em>文件名 t5 >,<em>lineno</em> <span class="sig-paren">)</span> </em></span></dt><dd><p><span class="yiyi-st" id="yiyi-462">从给定的字符串中提取所有doctest示例,并将它们收集到一个<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象中。</span></p><p><span class="yiyi-st" id="yiyi-463"><em>globs</em>,<em>name</em>,<em>filename</em>和<em>lineno</em>是新的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象的属性。</span><span class="yiyi-st" id="yiyi-464">有关更多信息,请参阅<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>的文档。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestParser.get_examples"><span class="yiyi-st" id="yiyi-465"> <code class="descname">get_examples</code><span class="sig-paren">(</span><em>string</em>, <em>name='<string>'</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-466">从给定的字符串中提取所有doctest示例,并将它们作为<a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>对象的列表返回。</span><span class="yiyi-st" id="yiyi-467">行号是从0开始的。</span><span class="yiyi-st" id="yiyi-468">可选参数<em>name</em>是标识此字符串的名称,仅用于出现错误消息。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestParser.parse"><span class="yiyi-st" id="yiyi-469"><code class="descname">parse</code> <span class="sig-paren">(</span> <em>string</em>,<em>name ='&lt; string&gt;'</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-470">将给定的字符串划分为示例和干预文本,并将它们作为交替<a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>和字符串的列表返回。</span><span class="yiyi-st" id="yiyi-471"><a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>的行号是基于0的。</span><span class="yiyi-st" id="yiyi-472">可选参数<em>name</em>是标识此字符串的名称,仅用于出现错误消息。</span></p></dd></dl></dd></dl></div><div class="section" id="doctestrunner-objects"><h3><span class="yiyi-st" id="yiyi-473">26.3.6.5. </span><span class="yiyi-st" id="yiyi-474">DocTestRunner对象</span></h3><dl class="class"><dt id="doctest.DocTestRunner"><span class="yiyi-st" id="yiyi-475"> <em class="property">class </em><code class="descclassname">doctest.</code><code class="descname">DocTestRunner</code><span class="sig-paren">(</span><em>checker=None</em>, <em>verbose=None</em>, <em>optionflags=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-476">一个处理类,用于在<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>中执行和验证交互式示例。</span></p><p><span class="yiyi-st" id="yiyi-477">预期输出与实际输出之间的比较由<a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>完成。</span><span class="yiyi-st" id="yiyi-478">这种比较可以用许多选项标志来定制;有关更多信息,请参阅<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span><span class="yiyi-st" id="yiyi-479">如果选项标志不足,则可以通过将<a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>的子类传递给构造函数来自定义比较。</span></p><p><span class="yiyi-st" id="yiyi-480">测试运行者的显示输出可以通过两种方式进行控制。</span><span class="yiyi-st" id="yiyi-481">首先,输出函数可以传递给<code class="xref py py-meth docutils literal"><span class="pre">TestRunner.run()</span></code>;这个函数将会被显示的字符串调用。</span><span class="yiyi-st" id="yiyi-482">它默认为<code class="docutils literal"><span class="pre">sys.stdout.write</span></code>。</span><span class="yiyi-st" id="yiyi-483">如果捕获输出是不够的,那么通过继承DocTestRunner并覆盖方法<a class="reference internal" href="#doctest.DocTestRunner.report_start" title="doctest.DocTestRunner.report_start"><code class="xref py py-meth docutils literal"><span class="pre">report_start()</span></code></a>,<a class="reference internal" href="#doctest.DocTestRunner.report_success" title="doctest.DocTestRunner.report_success"><code class="xref py py-meth docutils literal"><span class="pre">report_success()</span></code></a>,<a class="reference internal" href="#doctest.DocTestRunner.report_unexpected_exception" title="doctest.DocTestRunner.report_unexpected_exception"><code class="xref py py-meth docutils literal"><span class="pre">report_unexpected_exception()</span></code></a>和<a class="reference internal" href="#doctest.DocTestRunner.report_failure" title="doctest.DocTestRunner.report_failure"><code class="xref py py-meth docutils literal"><span class="pre">report_failure()</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-484">可选的关键字参数<em>checker</em>指定了<a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>对象(或插入替换),用于比较期望的输出和doctest示例的实际输出。</span></p><p><span class="yiyi-st" id="yiyi-485">可选的关键字参数<em>verbose</em>控制着<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的详细程度。</span><span class="yiyi-st" id="yiyi-486">如果<em>verbose</em>为<code class="docutils literal"><span class="pre">True</span></code>,则会在每个示例运行时打印有关每个示例的信息。</span><span class="yiyi-st" id="yiyi-487">如果<em>verbose</em>为<code class="docutils literal"><span class="pre">False</span></code>,则仅打印故障。</span><span class="yiyi-st" id="yiyi-488">如果未指定<em>verbose</em>或<code class="docutils literal"><span class="pre">None</span></code>,则使用详细输出,如果使用命令行开关<code class="docutils literal"><span class="pre">-v</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-489">可选关键字参数<em>optionflags</em>可用于控制测试运行器如何将预期输出与实际输出进行比较,以及它如何显示故障。</span><span class="yiyi-st" id="yiyi-490">有关更多信息,请参阅<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span></p><p><span class="yiyi-st" id="yiyi-491"><a class="reference internal" href="#doctest.DocTestParser" title="doctest.DocTestParser"><code class="xref py py-class docutils literal"><span class="pre">DocTestParser</span></code></a> defines the following methods:</span></p><dl class="method"><dt id="doctest.DocTestRunner.report_start"><span class="yiyi-st" id="yiyi-492"> <code class="descname">report_start</code><span class="sig-paren">(</span><em>out</em>, <em>test</em>, <em>example</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-493">报告测试运行人员即将处理给出的示例。</span><span class="yiyi-st" id="yiyi-494">提供此方法以允许<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的子类自定义其输出;它不应该直接调用。</span></p><p><span class="yiyi-st" id="yiyi-495"><em>example</em> is the example about to be processed. </span><span class="yiyi-st" id="yiyi-496"><em>test</em>是包含示例的测试<em>。</em></span><span class="yiyi-st" id="yiyi-497"><em>out</em>是传递给<a class="reference internal" href="#doctest.DocTestRunner.run" title="doctest.DocTestRunner.run"><code class="xref py py-meth docutils literal"><span class="pre">DocTestRunner.run()</span></code></a>的输出函数。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestRunner.report_success"><span class="yiyi-st" id="yiyi-498"><code class="descname">report_success</code> <span class="sig-paren">(</span> <em>out</em>,<em>test</em>,<em>示例</em>,<em>> <span class="sig-paren">) T6> </span></em></span></dt><dd><p><span class="yiyi-st" id="yiyi-499">报告给出的示例已成功运行。</span><span class="yiyi-st" id="yiyi-500">提供此方法以允许<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的子类自定义其输出;它不应该直接调用。</span></p><p><span class="yiyi-st" id="yiyi-501"><em>example</em> is the example about to be processed. </span><span class="yiyi-st" id="yiyi-502"><em>得到</em>是示例的实际输出。</span><span class="yiyi-st" id="yiyi-503"><em>test</em>是包含<em>示例</em>的测试。</span><span class="yiyi-st" id="yiyi-504"><em>out</em>是传递给<a class="reference internal" href="#doctest.DocTestRunner.run" title="doctest.DocTestRunner.run"><code class="xref py py-meth docutils literal"><span class="pre">DocTestRunner.run()</span></code></a>的输出函数。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestRunner.report_failure"><span class="yiyi-st" id="yiyi-505"><code class="descname">report_failure</code> <span class="sig-paren">(</span> <em>out</em>,<em>test</em>,<em>示例</em>,<em>> <span class="sig-paren">) T6> </span></em></span></dt><dd><p><span class="yiyi-st" id="yiyi-506">报告给出的例子失败。</span><span class="yiyi-st" id="yiyi-507">提供此方法以允许<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的子类自定义其输出;它不应该直接调用。</span></p><p><span class="yiyi-st" id="yiyi-508"><em>example</em> is the example about to be processed. </span><span class="yiyi-st" id="yiyi-509"><em>得到</em>是示例的实际输出。</span><span class="yiyi-st" id="yiyi-510"><em>test</em>是包含<em>示例</em>的测试。</span><span class="yiyi-st" id="yiyi-511"><em>out</em>是传递给<a class="reference internal" href="#doctest.DocTestRunner.run" title="doctest.DocTestRunner.run"><code class="xref py py-meth docutils literal"><span class="pre">DocTestRunner.run()</span></code></a>的输出函数。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestRunner.report_unexpected_exception"><span class="yiyi-st" id="yiyi-512"><code class="descname">report_unexpected_exception</code> <span class="sig-paren">(</span> <em>out</em>,<em>test</em>,<em>示例</em>,<em>exc_info t5 > <span class="sig-paren">) T6> </span></em></span></dt><dd><p><span class="yiyi-st" id="yiyi-513">报告给出的示例引发了意外的异常。</span><span class="yiyi-st" id="yiyi-514">提供此方法以允许<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的子类自定义其输出;它不应该直接调用。</span></p><p><span class="yiyi-st" id="yiyi-515"><em>example</em> is the example about to be processed. </span><span class="yiyi-st" id="yiyi-516"><em>exc_info</em>是包含有关意外异常(由<a class="reference internal" href="sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal"><span class="pre">sys.exc_info()</span></code></a>)返回的信息的元组。</span><span class="yiyi-st" id="yiyi-517"><em>test</em>是包含<em>示例</em>的测试。</span><span class="yiyi-st" id="yiyi-518"><em>out</em>是传递给<a class="reference internal" href="#doctest.DocTestRunner.run" title="doctest.DocTestRunner.run"><code class="xref py py-meth docutils literal"><span class="pre">DocTestRunner.run()</span></code></a>的输出函数。</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestRunner.run"><span class="yiyi-st" id="yiyi-519"> <code class="descname">run</code><span class="sig-paren">(</span><em>test</em>, <em>compileflags=None</em>, <em>out=None</em>, <em>clear_globs=True</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-520">在<em>test</em>(a <a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象)中运行示例,并使用写入函数<em>out</em>显示结果。</span></p><p><span class="yiyi-st" id="yiyi-521">这些示例在命名空间<code class="docutils literal"><span class="pre">test.globs</span></code>中运行。</span><span class="yiyi-st" id="yiyi-522">如果<em>clear_globs</em>为true(缺省值),则此测试运行后将清除此名称空间以帮助进行垃圾回收。</span><span class="yiyi-st" id="yiyi-523">如果您想在测试完成后检查名称空间,请使用<em>clear_globs = False</em>。</span></p><p><span class="yiyi-st" id="yiyi-524"><em>compileflags</em>给出了运行示例时Python编译器应该使用的一组标志。</span><span class="yiyi-st" id="yiyi-525">如果未指定,则它将默认为适用于<em>globs</em>的future-import标志集。</span></p><p><span class="yiyi-st" id="yiyi-526">The output of each example is checked using the <a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>‘s output checker, and the results are formatted by the <code class="xref py py-meth docutils literal"><span class="pre">DocTestRunner.report_*()</span></code> methods.</span></p></dd></dl><dl class="method"><dt id="doctest.DocTestRunner.summarize"><span class="yiyi-st" id="yiyi-527"><code class="descname">总结 T0> <span class="sig-paren">( T1> <em>详细=无 T2> <span class="sig-paren">) T3> </span></em></span></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-528">Print a summary of all the test cases that have been run by this DocTestRunner, and return a <a class="reference internal" href="../glossary.html#term-named-tuple"><span class="xref std std-term">named tuple</span></a> <code class="docutils literal"><span class="pre">TestResults(failed,</span> <span class="pre">attempted)</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-529">可选的<em>verbose</em>参数控制摘要的详细程度。</span><span class="yiyi-st" id="yiyi-530">如果未指定详细程度,则使用<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的详细程度。</span></p></dd></dl></dd></dl></div><div class="section" id="outputchecker-objects"><h3><span class="yiyi-st" id="yiyi-531">26.3.6.6. </span><span class="yiyi-st" id="yiyi-532">OutputChecker对象</span></h3><dl class="class"><dt id="doctest.OutputChecker"><span class="yiyi-st" id="yiyi-533"><em class="property">class</em> <code class="descclassname">doctest。</code> <code class="descname">OutputChecker</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-534">用于检查doctest示例的实际输出是否与预期输出匹配的类。</span><span class="yiyi-st" id="yiyi-535"><a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>定义了两种方法:<a class="reference internal" href="#doctest.OutputChecker.check_output" title="doctest.OutputChecker.check_output"><code class="xref py py-meth docutils literal"><span class="pre">check_output()</span></code></a>,它比较给定的一对输出,如果匹配则返回true;和<a class="reference internal" href="#doctest.OutputChecker.output_difference" title="doctest.OutputChecker.output_difference"><code class="xref py py-meth docutils literal"><span class="pre">output_difference()</span></code></a>,它返回描述两个输出之间差异的字符串。</span></p><p><span class="yiyi-st" id="yiyi-536"><a class="reference internal" href="#doctest.OutputChecker" title="doctest.OutputChecker"><code class="xref py py-class docutils literal"><span class="pre">OutputChecker</span></code></a>定义了以下方法:</span></p><dl class="method"><dt id="doctest.OutputChecker.check_output"><span class="yiyi-st" id="yiyi-537"><code class="descname">check_output</code> <span class="sig-paren">(</span> <em>want</em>,<em>got</em>,<em>optionflags</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-538">如果示例(<em>got</em>)的实际输出与预期输出(<em>want</em>)匹配,则返回<code class="docutils literal"><span class="pre">True</span></code>。</span><span class="yiyi-st" id="yiyi-539">如果这些字符串相同,则始终认为它们匹配;但取决于测试运行器使用的选项标志,还可以使用几种非精确匹配类型。</span><span class="yiyi-st" id="yiyi-540">有关选项标志的更多信息,请参见<a class="reference internal" href="#doctest-options"><span>Option Flags</span></a>部分。</span></p></dd></dl><dl class="method"><dt id="doctest.OutputChecker.output_difference"><span class="yiyi-st" id="yiyi-541"><code class="descname">output_difference</code> <span class="sig-paren">(</span> <em>example</em>,<em>got</em>,<em>optionflags</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-542">返回描述给定示例(<em>示例</em>)的预期输出和实际输出(<em>获得</em>)之间差异的字符串。</span><span class="yiyi-st" id="yiyi-543"><em>optionflags</em>是用于比较<em>want</em>和<em>got</em>的选项标志集。</span></p></dd></dl></dd></dl></div></div><div class="section" id="debugging"><h2><span class="yiyi-st" id="yiyi-544">26.3.7. </span><span class="yiyi-st" id="yiyi-545">调试</span></h2><p><span class="yiyi-st" id="yiyi-546">Doctest提供了几种调试doctest示例的机制:</span></p><ul><li><p class="first"><span class="yiyi-st" id="yiyi-547">Several functions convert doctests to executable Python programs, which can be run under the Python debugger, <a class="reference internal" href="pdb.html#module-pdb" title="pdb: The Python debugger for interactive interpreters."><code class="xref py py-mod docutils literal"><span class="pre">pdb</span></code></a>.</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-548"><a class="reference internal" href="#doctest.DebugRunner" title="doctest.DebugRunner"><code class="xref py py-class docutils literal"><span class="pre">DebugRunner</span></code></a>类是<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的一个子类,它引发了第一个失败示例的异常,其中包含有关该示例的信息。</span><span class="yiyi-st" id="yiyi-549">该信息可用于对示例执行事后调试。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-550">由<a class="reference internal" href="#doctest.DocTestSuite" title="doctest.DocTestSuite"><code class="xref py py-func docutils literal"><span class="pre">DocTestSuite()</span></code></a>生成的<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>个案支持由<a class="reference internal" href="unittest.html#unittest.TestCase" title="unittest.TestCase"><code class="xref py py-class docutils literal"><span class="pre">unittest.TestCase</span></code></a>定义的<a class="reference internal" href="#doctest.debug" title="doctest.debug"><code class="xref py py-meth docutils literal"><span class="pre">debug()</span></code></a>方法。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-551">您可以在doctest示例中添加对<a class="reference internal" href="pdb.html#pdb.set_trace" title="pdb.set_trace"><code class="xref py py-func docutils literal"><span class="pre">pdb.set_trace()</span></code></a>的调用,并且在执行该行时将放入Python调试器。</span><span class="yiyi-st" id="yiyi-552">然后你可以检查变量的当前值,等等。</span><span class="yiyi-st" id="yiyi-553">例如,假设<code class="file docutils literal"><span class="pre">a.py</span></code>仅包含此模块docstring:</span></p><pre><code class="language-python"><span></span><span class="sd">"""</span>
|
||
<span class="sd">>>> def f(x):</span>
|
||
<span class="sd">... g(x*2)</span>
|
||
<span class="sd">>>> def g(x):</span>
|
||
<span class="sd">... print(x+3)</span>
|
||
<span class="sd">... import pdb; pdb.set_trace()</span>
|
||
<span class="sd">>>> f(3)</span>
|
||
<span class="sd">9</span>
|
||
<span class="sd">"""</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-554">然后,一个交互式Python会话可能如下所示:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">a</span><span class="o">,</span> <span class="nn">doctest</span>
|
||
<span class="gp">>>> </span><span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
|
||
<span class="go">--Return--</span>
|
||
<span class="go">> <doctest a[1]>(3)g()->None</span>
|
||
<span class="go">-> import pdb; pdb.set_trace()</span>
|
||
<span class="go">(Pdb) list</span>
|
||
<span class="go"> 1 def g(x):</span>
|
||
<span class="go"> 2 print(x+3)</span>
|
||
<span class="go"> 3 -> import pdb; pdb.set_trace()</span>
|
||
<span class="go">[EOF]</span>
|
||
<span class="go">(Pdb) p x</span>
|
||
<span class="go">6</span>
|
||
<span class="go">(Pdb) step</span>
|
||
<span class="go">--Return--</span>
|
||
<span class="go">> <doctest a[0]>(2)f()->None</span>
|
||
<span class="go">-> g(x*2)</span>
|
||
<span class="go">(Pdb) list</span>
|
||
<span class="go"> 1 def f(x):</span>
|
||
<span class="go"> 2 -> g(x*2)</span>
|
||
<span class="go">[EOF]</span>
|
||
<span class="go">(Pdb) p x</span>
|
||
<span class="go">3</span>
|
||
<span class="go">(Pdb) step</span>
|
||
<span class="go">--Return--</span>
|
||
<span class="go">> <doctest a[2]>(1)?()->None</span>
|
||
<span class="go">-> f(3)</span>
|
||
<span class="go">(Pdb) cont</span>
|
||
<span class="go">(0, 3)</span>
|
||
<span class="go">>>></span>
|
||
</code></pre></li></ul><p><span class="yiyi-st" id="yiyi-555">将doctests转换为Python代码的函数,并可能在调试器下运行综合代码:</span></p><dl class="function"><dt id="doctest.script_from_examples"><span class="yiyi-st" id="yiyi-556"><code class="descclassname">文档测试 T0> <code class="descname"> script_from_examples T1> <span class="sig-paren">( T2> <em>取值 T3> <span class="sig-paren">) T4> </span></em></span></code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-557">将带有示例的文本转换为脚本。</span></p><p><span class="yiyi-st" id="yiyi-558">参数<em>s</em>是一个包含doctest示例的字符串。</span><span class="yiyi-st" id="yiyi-559">该字符串被转换为Python脚本,其中<em>s</em>中的doctest示例转换为常规代码,其他所有内容都转换为Python注释。</span><span class="yiyi-st" id="yiyi-560">生成的脚本作为字符串返回。</span><span class="yiyi-st" id="yiyi-561">例如,</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">doctest</span><span class="o">.</span><span class="n">script_from_examples</span><span class="p">(</span><span class="s2">r"""</span>
|
||
<span class="s2"> Set x and y to 1 and 2.</span>
|
||
<span class="s2"> >>> x, y = 1, 2</span>
|
||
|
||
<span class="s2"> Print their sum:</span>
|
||
<span class="s2"> >>> print(x+y)</span>
|
||
<span class="s2"> 3</span>
|
||
<span class="s2">"""</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-562">显示:</span></p><pre><code class="language-python"><span></span><span class="c1"># Set x and y to 1 and 2.</span>
|
||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span>
|
||
<span class="c1">#</span>
|
||
<span class="c1"># Print their sum:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span>
|
||
<span class="c1"># Expected:</span>
|
||
<span class="c1">## 3</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-563">该函数在其他函数的内部使用(请参见下文),但是当您想要将交互式Python会话转换为Python脚本时,该函数也很有用。</span></p></dd></dl><dl class="function"><dt id="doctest.testsource"><span class="yiyi-st" id="yiyi-564"> <code class="descclassname">doctest.</code><code class="descname">testsource</code><span class="sig-paren">(</span><em>module</em>, <em>name</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-565">将对象的doctest转换为脚本。</span></p><p><span class="yiyi-st" id="yiyi-566">参数<em>模块</em>是一个模块对象或模块的虚线名称,包含其doctests感兴趣的对象。</span><span class="yiyi-st" id="yiyi-567">参数<em>name</em>是具有感兴趣的doctests的对象的名称(在模块内)。</span><span class="yiyi-st" id="yiyi-568">结果是一个字符串,包含对象的文档字符串转换为Python脚本,如上面的<a class="reference internal" href="#doctest.script_from_examples" title="doctest.script_from_examples"><code class="xref py py-func docutils literal"><span class="pre">script_from_examples()</span></code></a>所述。</span><span class="yiyi-st" id="yiyi-569">例如,如果模块<code class="file docutils literal"><span class="pre">a.py</span></code>包含一个顶级函数<code class="xref py py-func docutils literal"><span class="pre">f()</span></code>,那么</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">a</span><span class="o">,</span> <span class="nn">doctest</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">doctest</span><span class="o">.</span><span class="n">testsource</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="s2">"a.f"</span><span class="p">))</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-570">打印一个脚本版本的函数<code class="xref py py-func docutils literal"><span class="pre">f()</span></code>的文档字符串,并将文档转换为代码,其余部分放在注释中。</span></p></dd></dl><dl class="function"><dt id="doctest.debug"><span class="yiyi-st" id="yiyi-571"> <code class="descclassname">doctest.</code><code class="descname">debug</code><span class="sig-paren">(</span><em>module</em>, <em>name</em>, <em>pm=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-572">调试对象的doctests。</span></p><p><span class="yiyi-st" id="yiyi-573"><em>module</em>和<em>name</em>参数与上面的函数<a class="reference internal" href="#doctest.testsource" title="doctest.testsource"><code class="xref py py-func docutils literal"><span class="pre">testsource()</span></code></a>相同。</span><span class="yiyi-st" id="yiyi-574">将命名对象的docstring的合成Python脚本写入临时文件,然后该文件在Python调试器<a class="reference internal" href="pdb.html#module-pdb" title="pdb: The Python debugger for interactive interpreters."><code class="xref py py-mod docutils literal"><span class="pre">pdb</span></code></a>的控制下运行。</span></p><p><span class="yiyi-st" id="yiyi-575">本地和全局执行上下文都使用<code class="docutils literal"><span class="pre">module.__dict__</span></code>的浅表副本。</span></p><p><span class="yiyi-st" id="yiyi-576">可选参数<em>pm</em>控制是否使用验尸调试。</span><span class="yiyi-st" id="yiyi-577">如果<em>pm</em>具有真值,则脚本文件将直接运行,并且调试程序只有在脚本通过引发未处理的异常终止时才会涉及。</span><span class="yiyi-st" id="yiyi-578">如果是,则通过<a class="reference internal" href="pdb.html#pdb.post_mortem" title="pdb.post_mortem"><code class="xref py py-func docutils literal"><span class="pre">pdb.post_mortem()</span></code></a>调用验尸调试,从未处理的异常中传递回溯对象。</span><span class="yiyi-st" id="yiyi-579">如果没有指定<em>pm</em>,或者为false,则通过将适当的<a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal"><span class="pre">exec()</span></code></a>调用传递给<a class="reference internal" href="pdb.html#pdb.run" title="pdb.run"><code class="xref py py-func docutils literal"><span class="pre">pdb.run()</span></code></a></span></p></dd></dl><dl class="function"><dt id="doctest.debug_src"><span class="yiyi-st" id="yiyi-580"> <code class="descclassname">doctest.</code><code class="descname">debug_src</code><span class="sig-paren">(</span><em>src</em>, <em>pm=False</em>, <em>globs=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-581">用字符串调试doctests。</span></p><p><span class="yiyi-st" id="yiyi-582">这与上面的函数<a class="reference internal" href="#doctest.debug" title="doctest.debug"><code class="xref py py-func docutils literal"><span class="pre">debug()</span></code></a>类似,只是通过<em>src</em>参数直接指定了包含doctest示例的字符串。</span></p><p><span class="yiyi-st" id="yiyi-583">可选参数<em>pm</em>的含义与上面的函数<a class="reference internal" href="#doctest.debug" title="doctest.debug"><code class="xref py py-func docutils literal"><span class="pre">debug()</span></code></a>中的含义相同。</span></p><p><span class="yiyi-st" id="yiyi-584">可选参数<em>globs</em>给出了一个字典,用作本地和全局执行上下文。</span><span class="yiyi-st" id="yiyi-585">如果未指定,或<code class="docutils literal"><span class="pre">None</span></code>,则使用空字典。</span><span class="yiyi-st" id="yiyi-586">如果指定,则使用字典的浅表副本。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-587"><a class="reference internal" href="#doctest.DebugRunner" title="doctest.DebugRunner"><code class="xref py py-class docutils literal"><span class="pre">DebugRunner</span></code></a>类以及它可能引发的特殊异常是测试框架作者最感兴趣的,并且在此仅作简要说明。</span><span class="yiyi-st" id="yiyi-588">查看源代码,特别是<a class="reference internal" href="#doctest.DebugRunner" title="doctest.DebugRunner"><code class="xref py py-class docutils literal"><span class="pre">DebugRunner</span></code></a>的文档字符串(这是一个doctest!)</span><span class="yiyi-st" id="yiyi-589">更多细节:</span></p><dl class="class"><dt id="doctest.DebugRunner"><span class="yiyi-st" id="yiyi-590"><em class="property">class</em> <code class="descclassname">doctest。</code> <code class="descname">DebugRunner</code> <span class="sig-paren">(</span> <em>checker =无</em>,<em>verbose =无</em>,<em>optionflags = 0</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-591"><a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的子类一旦遇到故障就会引发异常。</span><span class="yiyi-st" id="yiyi-592">如果发生意外异常,将引发<a class="reference internal" href="#doctest.UnexpectedException" title="doctest.UnexpectedException"><code class="xref py py-exc docutils literal"><span class="pre">UnexpectedException</span></code></a>异常,其中包含测试,示例和原始异常。</span><span class="yiyi-st" id="yiyi-593">如果输出不匹配,则会引发一个<a class="reference internal" href="#doctest.DocTestFailure" title="doctest.DocTestFailure"><code class="xref py py-exc docutils literal"><span class="pre">DocTestFailure</span></code></a>异常,其中包含测试,示例和实际输出。</span></p><p><span class="yiyi-st" id="yiyi-594">有关构造函数参数和方法的信息,请参阅<a class="reference internal" href="#doctest-advanced-api"><span>Advanced API</span></a>部分中<a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a>的文档。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-595">There are two exceptions that may be raised by <a class="reference internal" href="#doctest.DebugRunner" title="doctest.DebugRunner"><code class="xref py py-class docutils literal"><span class="pre">DebugRunner</span></code></a> instances:</span></p><dl class="exception"><dt id="doctest.DocTestFailure"><span class="yiyi-st" id="yiyi-596"> <em class="property">exception </em><code class="descclassname">doctest.</code><code class="descname">DocTestFailure</code><span class="sig-paren">(</span><em>test</em>, <em>example</em>, <em>got</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-597">An exception raised by <a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a> to signal that a doctest example’s actual output did not match its expected output. </span><span class="yiyi-st" id="yiyi-598">构造函数参数用于初始化相同名称的属性。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-599"><a class="reference internal" href="#doctest.DocTestFailure" title="doctest.DocTestFailure"><code class="xref py py-exc docutils literal"><span class="pre">DocTestFailure</span></code></a> defines the following attributes:</span></p><dl class="attribute"><dt id="doctest.DocTestFailure.test"><span class="yiyi-st" id="yiyi-600"><code class="descclassname"> DocTestFailure。 T0> <code class="descname">测试 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-601">示例失败时正在运行的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTestFailure.example"><span class="yiyi-st" id="yiyi-602"><code class="descclassname"> DocTestFailure。 T0> <code class="descname">例如 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-603">失败的<a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>。</span></p></dd></dl><dl class="attribute"><dt id="doctest.DocTestFailure.got"><span class="yiyi-st" id="yiyi-604"><code class="descclassname"> DocTestFailure。 T0> <code class="descname">得到 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-605">示例的实际输出。</span></p></dd></dl><dl class="exception"><dt id="doctest.UnexpectedException"><span class="yiyi-st" id="yiyi-606"><em class="property">异常</em> <code class="descclassname">doctest。</code> <code class="descname">UnexpectedException</code> <span class="sig-paren">(</span> <em>test</em>,<em>example</em> ,<em>exc_info</em> <span class="sig-paren">)</span> </span></dt><dd><p><span class="yiyi-st" id="yiyi-607">An exception raised by <a class="reference internal" href="#doctest.DocTestRunner" title="doctest.DocTestRunner"><code class="xref py py-class docutils literal"><span class="pre">DocTestRunner</span></code></a> to signal that a doctest example raised an unexpected exception. </span><span class="yiyi-st" id="yiyi-608">构造函数参数用于初始化相同名称的属性。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-609"><a class="reference internal" href="#doctest.UnexpectedException" title="doctest.UnexpectedException"><code class="xref py py-exc docutils literal"><span class="pre">UnexpectedException</span></code></a>定义了以下属性:</span></p><dl class="attribute"><dt id="doctest.UnexpectedException.test"><span class="yiyi-st" id="yiyi-610"><code class="descclassname"> UnexpectedException。 T0> <code class="descname">测试 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-611">示例失败时正在运行的<a class="reference internal" href="#doctest.DocTest" title="doctest.DocTest"><code class="xref py py-class docutils literal"><span class="pre">DocTest</span></code></a>对象。</span></p></dd></dl><dl class="attribute"><dt id="doctest.UnexpectedException.example"><span class="yiyi-st" id="yiyi-612"><code class="descclassname"> UnexpectedException。 T0> <code class="descname">例如 T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-613">失败的<a class="reference internal" href="#doctest.Example" title="doctest.Example"><code class="xref py py-class docutils literal"><span class="pre">Example</span></code></a>。</span></p></dd></dl><dl class="attribute"><dt id="doctest.UnexpectedException.exc_info"><span class="yiyi-st" id="yiyi-614"><code class="descclassname"> UnexpectedException。 T0> <code class="descname"> exc_info T1> </code></code></span></dt><dd><p><span class="yiyi-st" id="yiyi-615">一个包含有关意外异常信息的元组,该元组由<a class="reference internal" href="sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal"><span class="pre">sys.exc_info()</span></code></a>返回。</span></p></dd></dl></div><div class="section" id="soapbox"><h2><span class="yiyi-st" id="yiyi-616">26.3.8. </span><span class="yiyi-st" id="yiyi-617">肥皂盒</span></h2><p><span class="yiyi-st" id="yiyi-618">As mentioned in the introduction, <a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a> has grown to have three primary uses:</span></p><ol class="arabic simple"><li><span class="yiyi-st" id="yiyi-619">检查文档字符串中的示例。</span></li><li><span class="yiyi-st" id="yiyi-620">回归测试。</span></li><li><span class="yiyi-st" id="yiyi-621">可执行文档/文字测试。</span></li></ol><p><span class="yiyi-st" id="yiyi-622">这些用途具有不同的要求,区分它们很重要。</span><span class="yiyi-st" id="yiyi-623">特别是,用不明确的测试用例填充文档字符串会导致错误的文档。</span></p><p><span class="yiyi-st" id="yiyi-624">在编写文档字符串时,请小心选择文档字符串示例。</span><span class="yiyi-st" id="yiyi-625">有一件艺术需要学习 - 起初可能并不自然。</span><span class="yiyi-st" id="yiyi-626">示例应该为文档增加真正的价值。</span><span class="yiyi-st" id="yiyi-627">一个很好的例子往往可以说很多话。</span><span class="yiyi-st" id="yiyi-628">如果谨慎处理,这些示例对您的用户来说将是非常宝贵的,并且会随着时间的推移和事情的变化而回报多次收集它们所需的时间。</span><span class="yiyi-st" id="yiyi-629">我仍然惊讶于我的一个<a class="reference internal" href="#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal"><span class="pre">doctest</span></code></a>示例在“无害”更改后停止工作的频率。</span></p><p><span class="yiyi-st" id="yiyi-630">Doctest也是回归测试的绝佳工具,特别是如果你不吝啬解释性文本。</span><span class="yiyi-st" id="yiyi-631">通过插入散文和例子,跟踪实际正在测试的内容以及为什么更容易。</span><span class="yiyi-st" id="yiyi-632">当一个测试失败时,好的散文可以使得更容易找出问题所在,以及应该如何解决问题。</span><span class="yiyi-st" id="yiyi-633">的确,您可以在基于代码的测试中编写大量的评论,但很少有程序员会这样做。</span><span class="yiyi-st" id="yiyi-634">许多人已经发现使用doctest方法会导致更清晰的测试。</span><span class="yiyi-st" id="yiyi-635">也许这只是因为doctest使编写散文比编写代码容易一些,而在代码中编写注释有点困难。</span><span class="yiyi-st" id="yiyi-636">我认为它比以上更深刻:编写基于doctest的测试时的自然态度是您想解释软件的优点,并用示例来说明它们。</span><span class="yiyi-st" id="yiyi-637">这反过来自然会导致以最简单的功能开始的测试文件,并在逻辑上进展到复杂性和边缘情况。</span><span class="yiyi-st" id="yiyi-638">一个连贯的叙述是结果,而不是一组孤立的函数,它们似乎随机地测试孤立的功能位。</span><span class="yiyi-st" id="yiyi-639">这是一种不同的态度,产生不同的结果,模糊了测试和解释之间的区别。</span></p><p><span class="yiyi-st" id="yiyi-640">回归测试最好局限于专用对象或文件。</span><span class="yiyi-st" id="yiyi-641">有几种组织测试的选项:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-642">将包含测试用例的文本文件编写为交互式示例,并使用<a class="reference internal" href="#doctest.testfile" title="doctest.testfile"><code class="xref py py-func docutils literal"><span class="pre">testfile()</span></code></a>或<a class="reference internal" href="#doctest.DocFileSuite" title="doctest.DocFileSuite"><code class="xref py py-func docutils literal"><span class="pre">DocFileSuite()</span></code></a>测试文件。</span><span class="yiyi-st" id="yiyi-643">这是推荐的,尽管对于从一开始就使用doctest设计的新项目来说,这是最容易做到的。</span></li><li><span class="yiyi-st" id="yiyi-644">定义名为<code class="docutils literal"><span class="pre">_regrtest_topic</span></code>的函数,其中包含单个文档字符串,其中包含指定主题的测试用例。</span><span class="yiyi-st" id="yiyi-645">这些功能可以包含在与模块相同的文件中,或者分离到单独的测试文件中。</span></li><li><span class="yiyi-st" id="yiyi-646">Define a <code class="docutils literal"><span class="pre">__test__</span></code> dictionary mapping from regression test topics to docstrings containing test cases.</span></li></ul><p><span class="yiyi-st" id="yiyi-647">当您将测试放入模块中时,模块本身可以成为测试运行者。</span><span class="yiyi-st" id="yiyi-648">当测试失败时,您可以安排测试运行者在调试问题时仅重新运行失败的doctest。</span><span class="yiyi-st" id="yiyi-649">这是一个这样的测试运行者的最小例子:</span></p><pre><code class="language-python"><span></span><span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
|
||
<span class="kn">import</span> <span class="nn">doctest</span>
|
||
<span class="n">flags</span> <span class="o">=</span> <span class="n">doctest</span><span class="o">.</span><span class="n">REPORT_NDIFF</span><span class="o">|</span><span class="n">doctest</span><span class="o">.</span><span class="n">FAIL_FAST</span>
|
||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
||
<span class="n">name</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="nb">globals</span><span class="p">():</span>
|
||
<span class="n">obj</span> <span class="o">=</span> <span class="nb">globals</span><span class="p">()[</span><span class="n">name</span><span class="p">]</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">obj</span> <span class="o">=</span> <span class="n">__test__</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
|
||
<span class="n">doctest</span><span class="o">.</span><span class="n">run_docstring_examples</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">globals</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">,</span>
|
||
<span class="n">optionflags</span><span class="o">=</span><span class="n">flags</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">fail</span><span class="p">,</span> <span class="n">total</span> <span class="o">=</span> <span class="n">doctest</span><span class="o">.</span><span class="n">testmod</span><span class="p">(</span><span class="n">optionflags</span><span class="o">=</span><span class="n">flags</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2"> failures out of </span><span class="si">{}</span><span class="s2"> tests"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fail</span><span class="p">,</span> <span class="n">total</span><span class="p">))</span>
|
||
</code></pre><p class="rubric"><span class="yiyi-st" id="yiyi-650">脚注</span></p><table class="docutils footnote" frame="void" id="id2" rules="none"><tbody valign="top"><tr><td class="label"><span class="yiyi-st" id="yiyi-651"><a class="fn-backref" href="#id1"> [1] T0></a></span></td><td><span class="yiyi-st" id="yiyi-652">不支持包含预期输出和异常的示例。</span><span class="yiyi-st" id="yiyi-653">试图猜测一个结束和另一个开始的地方太容易出错,这也会导致一个令人困惑的测试。</span></td></tr></tbody></table></div></div></div> |