sphinx.ext.doctest – ドキュメント内のスニペットをテストする

ドキュメントにコードのスニペットを含めて、実行結果を示すことは、しばしば役立ちます。しかし、ドキュメントがコードに合わせて最新の状態に保たれていることを確認することが重要です。

この拡張機能を使用すると、ドキュメント内のこのようなコードスニペットを自然な方法でテストできます。ここに示されているようにコードブロックをマークすると、doctest ビルダーがそれらを収集し、doctest テストとして実行します。

各ドキュメント内で、各スニペットを *グループ* に割り当てることができます。各グループは以下で構成されます。

  • 0 個以上の *セットアップコード* ブロック(例:テストするモジュールをインポートする)

  • 1 つ以上の *テスト* ブロック

doctest ビルダーでドキュメントをビルドする場合、グループは各ドキュメントに対して収集され、順に実行されます。最初にセットアップコードブロックを実行し、次にファイルに表示される順序でテストブロックを実行します。

テストブロックには 2 種類あります。

  • *doctest スタイル* ブロックは、Python コード(インタプリタプロンプトを含む)と出力を交互に表示することで、インタラクティブセッションを模倣します。

  • *コード出力スタイル* ブロックは、通常の Python コードと、オプションでそのコードの出力で構成されます。

ディレクティブ

以下の *group* 引数は次のように解釈されます。空の場合、ブロックは default という名前のグループに割り当てられます。* の場合、ブロックは(default グループを含む)すべてのグループに割り当てられます。それ以外の場合は、グループ名のカンマ区切りリストである必要があります。

.. testsetup:: [group]

セットアップコードブロック。このコードは他のビルダーの出力には表示されませんが、属するグループの doctest の前に実行されます。

.. testcleanup:: [group]

クリーンアップコードブロック。このコードは他のビルダーの出力には表示されませんが、属するグループの doctest の後に実行されます。

バージョン 1.1 で追加されました。

.. doctest:: [group]

doctest スタイルのコードブロック。標準の doctest フラグを使用して、実際の出力と出力として指定したものを比較する方法を制御できます。フラグのデフォルトセットは、doctest_default_flags 設定変数によって指定されます。

このディレクティブは 5 つのオプションをサポートしています

  • hide、フラグオプション。他のビルダーで doctest ブロックを非表示にします。デフォルトでは、強調表示された doctest ブロックとして表示されます。

  • options、文字列オプション。テスト内の各例に適用される doctest フラグのカンマ区切りリストを指定するために使用できます。(doctest コメントで例ごとに明示的なフラグを指定することもできますが、他のビルダーにも表示されます。)

  • pyversion、文字列オプション。テストする例に必要な Python バージョンを指定するために使用できます。たとえば、次のケースでは、例は 3.12 より大きい Python バージョンでのみテストされます

    .. doctest::
       :pyversion: > 3.12
    

    次のオペランドがサポートされています

    • ~=:互換性のあるリリース句

    • ==:バージョン一致句

    • !=:バージョン除外句

    • <=>=:包括的な順序比較句

    • <>:排他的な順序比較句

    • ===:任意の等価句。

    pyversion オプションには、PEP-440: バージョン指定子 が続きます。

    バージョン 1.6 で追加されました。

    バージョン 1.7 で変更: PEP-440 のオペランドと表記法をサポート

  • trim-doctest-flags および no-trim-doctest-flags、フラグオプション。行末の doctest フラグ(# doctest: FLAG, ... のように見えるコメント)と <BLANKLINE> マーカーは、個別に削除されます(または削除されません)。デフォルトは trim-doctest-flags です。

標準の doctest と同様に、予想される出力で空白行を通知するには <BLANKLINE> を使用する必要があることに注意してください。<BLANKLINE> は、プレゼンテーション出力(HTML、LaTeX など)を構築する際に削除されます。

また、doctest のようにインライン doctest オプションを指定することもできます

>>> datetime.date.now()   # doctest: +SKIP
datetime.date(2008, 1, 1)

テスト実行時に考慮されますが、プレゼンテーション出力からは削除されます。

.. testcode:: [group]

コード出力スタイルテスト用のコードブロック。

このディレクティブは 3 つのオプションをサポートしています

  • hide、フラグオプション。他のビルダーでコードブロックを非表示にします。デフォルトでは、強調表示されたコードブロックとして表示されます。

  • trim-doctest-flags および no-trim-doctest-flags、フラグオプション。行末の doctest フラグ(# doctest: FLAG, ... のように見えるコメント)と <BLANKLINE> マーカーは、個別に削除されます(または削除されません)。デフォルトは trim-doctest-flags です。

注記

testcode ブロックのコードは、含まれるステートメントの数に関係なく、常に一度にすべて実行されます。したがって、裸の式に対しては出力が生成されません。代わりに print を使用してください。例

.. testcode::

   1+1         # this will give no output!
   print(2+2)  # this will give output

.. testoutput::

   4

また、doctest モジュールは通常の出力と例外メッセージを同じスニペットで混在させることをサポートしていないため、これは testcode/testoutput にも適用されることに注意してください。

.. testoutput:: [group]

最後の testcode ブロックに対応する出力、または例外メッセージ。

このディレクティブは 4 つのオプションをサポートしています

  • hide はフラグオプションで、他のビルダーで出力ブロックを非表示にします。デフォルトでは、ハイライトなしのリテラルブロックとして表示されます。

  • options は文字列オプションで、通常の doctest ブロックのように doctest フラグ (カンマ区切り) を指定するために使用できます。

  • trim-doctest-flags および no-trim-doctest-flags、フラグオプション。行末の doctest フラグ(# doctest: FLAG, ... のように見えるコメント)と <BLANKLINE> マーカーは、個別に削除されます(または削除されません)。デフォルトは trim-doctest-flags です。

.. testcode::

   print('Output     text.')

.. testoutput::
   :hide:
   :options: -ELLIPSIS, +NORMALIZE_WHITESPACE

   Output text.

以下は、ディレクティブの使用例です。doctest を介したテストと、testcode および testoutput を介したテストは同等です。

The parrot module
=================

.. testsetup:: *

   import parrot

The parrot module is a module about parrots.

Doctest example:

.. doctest::

   >>> parrot.voom(3000)
   This parrot wouldn't voom if you put 3000 volts through it!

Test-Output example:

.. testcode::

   parrot.voom(3000)

This would output:

.. testoutput::

   This parrot wouldn't voom if you put 3000 volts through it!

条件付きでテストをスキップする

skipif は文字列オプションで、条件付きでディレクティブをスキップするために使用できます。これは、環境(ハードウェア、ネットワーク/VPN、オプションの依存関係、または依存関係の異なるバージョン)に応じて異なるテストセットを実行する必要がある場合に役立ちます。skipif オプションは、すべての doctest ディレクティブでサポートされています。以下は、異なるディレクティブで使用する場合の skipif の典型的なユースケースです。

  • testsetup および testcleanup

    • テストのセットアップやクリーンアップを条件付きでスキップする

    • 環境ごとにセットアップ/クリーンアップコードをカスタマイズする

  • doctest

    • テストとその出力検証の両方を条件付きでスキップする

  • testcode

    • テストを条件付きでスキップする

    • 環境ごとにテストコードをカスタマイズする

  • testoutput

    • スキップされたテストの出力アサーションを条件付きでスキップする

    • 環境に応じて異なる出力を期待する

skipif オプションの値は、Python 式として評価されます。結果が真の値である場合、ディレクティブは、ファイルにまったく存在しないかのようにテスト実行から省略されます。

式を繰り返す代わりに、doctest_global_setup 設定オプションを使用して、変数に割り当ててから代わりに使用できます。

Pandas がインストールされていない場合にいくつかのテストをスキップする例を次に示します。

conf.py
extensions = ['sphinx.ext.doctest']
doctest_global_setup = '''
try:
    import pandas as pd
except ImportError:
    pd = None
'''
contents.rst
.. testsetup::
   :skipif: pd is None

   data = pd.Series([42])

.. doctest::
   :skipif: pd is None

   >>> data.iloc[0]
   42

.. testcode::
   :skipif: pd is None

   print(data.iloc[-1])

.. testoutput::
   :skipif: pd is None

   42

設定

doctest 拡張機能は、次の設定値を使用します。

doctest_default_flags

デフォルトでは、これらのオプションが有効になっています

  • ELLIPSIS。これにより、実際の出力のあらゆるものに一致する省略記号を期待される出力に記述できます。

  • IGNORE_EXCEPTION_DETAIL。これにより、左端のコロンの後に続くすべてと、例外名のモジュール情報が無視されます。

  • DONT_ACCEPT_TRUE_FOR_1。「1」が指定された出力で「True」を拒否します。この置換を受け入れるデフォルトの動作は、Python 2.2 より前の時代の名残です。

バージョン 1.5 で追加されました。

doctest_show_successes

デフォルトは True です。成功が報告されるかどうかを制御します。

多数の doctest を含むプロジェクトでは、失敗のみを強調表示するためにこれを False に設定すると便利な場合があります。

バージョン 7.2 で追加されました。

doctest_path

doctest ビルダーが使用されるときに、sys.path に追加されるディレクトリのリストです。(絶対パスが含まれていることを確認してください。)

doctest_global_setup

テストされるすべてのファイルおよびすべてのグループに対して、testsetup ディレクティブに配置されたかのように扱われる Python コード。これを使用して、たとえば、doctest で常に必要となるモジュールをインポートできます。

バージョン 0.6 で追加されました。

doctest_global_cleanup

テストされるすべてのファイルおよびすべてのグループに対して、testcleanup ディレクティブに配置されたかのように扱われる Python コード。これを使用して、たとえば、テストが残した一時ファイルを削除できます。

バージョン 1.1 で追加されました。

doctest_test_doctest_blocks

これが空でない文字列(デフォルトは 'default')の場合、標準の reStructuredText doctest ブロックもテストされます。それらは、指定されたグループ名に割り当てられます。

reStructuredText doctest ブロックは、次のように、独自の段落に配置された単なる doctest です。

Some documentation text.

>>> print(1)
1

Some more documentation text.

(doctest ブロックを導入するために特別な :: が使用されていないことに注意してください。docutils は、先頭の >>> から認識します。また、追加のインデントは使用されていませんが、害はありません。)

この値がデフォルト値のままの場合、上記のコードスニペットは、doctest ビルダーによって次のように解釈されます。

Some documentation text.

.. doctest::

   >>> print(1)
   1

Some more documentation text.

この機能を使用すると、autodoc 拡張機能に含まれる docstring 内の doctest を、特別なディレクティブでマークアップせずに簡単にテストできます。

ただし、reStructuredText doctest ブロックには空白行を含めることができないことに注意してください。それらは、1つのブロックの終了と別のブロックの開始として解釈されます。また、<BLANKLINE> および # doctest: オプションの削除は、doctest ブロックでのみ機能しますが、trim_doctest_flags を設定して、Python コンソールコンテンツを含むすべてのコードブロックでそれを実現できます。