5.2.6.1 オプションフラグとディレクティブ

doctest では、その挙動の様々な側面をたくさんのオプションフラグで制御 しています。各フラグのシンボル名はモジュールの定数として提供されて おり、論理和で組み合わせて様々な関数に渡せるようになっています。 シンボル名は doctest のディレクティブ (directive, 下記参照) としても 使えます。

最初に説明するオプション群は、 テストのセマンティクスを決めます。 すなわち、実際にテストを実行したときの出力と例題中の予想出力とが 一致しているかどうかを doctest がどうやって判断するかを制御します:

DONT_ACCEPT_TRUE_FOR_1
デフォルトでは、予想出力ブロックに単に1 だけが入っており、 実際の出力ブロックに 1 または True だけが入って いた場合、これらの出力は一致しているとみなされます。 0False の場合も同様です。 DONT_ACCEPT_TRUE_FOR_1 を指定すると、こうした値の読み替え を行いません。デフォルトの挙動で読み替えを行うのは、最近の Python で 多くの関数の戻り値型が整数型からブール型に変更されたことに対応する ためです; 読み替えを行う場合、"通常の整数" の出力を予想出力とする ような doctest も動作します。このオプションはそのうち無くなるでしょうが、 ここ数年はそのままでしょう。

DONT_ACCEPT_BLANKLINE
デフォルトでは、予想出力ブロックに <BLANKLINE> だけの 入った行がある場合、その行は実際の出力における空行に一致する ようになります。完全な空行を入れてしまうと予想出力がそこで 終わっているとみなされてしまうため、空行を予想出力に入れたい 場合にはこの方法を使わねばなりません。 DONT_ACCEPT_BLANKLINE を指定すると、 <BLANKLINE> の読み替えを行わなくなります。

NORMALIZE_WHITESPACE
このフラグを指定すると、空白 (空白と改行文字) の列は互いに等価であると みなします。予想出力における任意の空白列は実際の出力における任意の 空白と一致します。デフォルトでは、空白は厳密に一致せねばなりません。 NORMALIZE_WHITESPACE は、予想出力の内容が非常に長いために、 ソースコード中でその内容を複数行に折り返して書きたい場合に特に便利です。

ELLIPSIS
このフラグを指定すると、予想出力中の省略記号マーカ (...) を実際の出力中の任意の部分文字列に一致させられます。部分文字列は 行境界にわたるものや空文字列を含みます。従って、このフラグを使うのは 単純な内容を対象にする場合にとどめましょう。複雑な使い方をすると、 正規表現に .* を使ったときのように "あらら、省略部分をマッチがえてる (match too much) !" と驚くことになりかねません。

IGNORE_EXCEPTION_DETAIL
このフラグを指定すると、予想される実行結果に例外が入るような例題で、 予想通りの型の例外が送出された場合に、例外の詳細情報が一致していなくても テストをパスさせます。例えば、予想出力が"ValueError: 42" であるような例題は、実際に送出された例外が"ValueError: 3*14" でも パスしますが、TypeError が送出されるといった場合には パスしません。

ELLIPSIS を使っても同様のことができ、 IGNORE_EXCEPTION_DETAIL は リリース 2.4 以前の Python を使う人がほとんどいなくなった時期を見計らって撤廃するかもしれないので 気をつけてください。それまでは、IGNORE_EXCEPTION_DETAIL は 2.4 以前の Python で例外の詳細については気にせずテストをパスさせるように doctest を書くための唯一の明確な方法です。例えば、

>>> (1, 2)[3] = 'moo' #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment

にすると、 Python 2.4 と Python 2.3 の両方でテストをパスさせられます。 というのは、例外の詳細情報は 2.4 で変更され、 "doesn't" から "does not" と書くようになったからです。

COMPARISON_FLAGS
上記の比較フラグ全ての論理和をとったビットマスクです。

二つ目のオプション群は、テストの失敗を報告する方法を制御します:

REPORT_UDIFF
このオプションを指定すると、複数行にわたる予想出力や実際の出力 を、一元化 (unified) diff を使って表示します。

REPORT_CDIFF
このオプションを指定すると、複数行にわたる予想出力や実際の出力 を、コンテキスト diff を使って表示します。

REPORT_NDIFF
このオプションを指定すると、予想出力と実際の出力との間の差分を よく知られているndiff.py ユーティリティと同じアルゴリズムを 使っている difflib.Differ で分析します。これは、行単位の差分 と同じように行内の差分にマーカをつけられるようにする唯一の手段です。 例えば、予想出力のある行に数字の 1 が入っていて、実際の出力 には l が入っている場合、不一致のおきているカラム位置を 示すキャレットの入った行が一行挿入されます。

REPORT_ONLY_FIRST_FAILURE
このオプションを指定すると、各 doctest で最初にエラーの起きた例題 だけを表示し、それ以後の例題の出力を抑制します。これにより、正しく 書かれた例題が、それ以前の例題の失敗によっておかしくなってしまった 場合に、doctest がそれを報告しないようになります。とはいえ、 最初に失敗を引き起こした例題とは関係なく誤って書かれた例題の 報告も抑制してしまいます。REPORT_ONLY_FIRST_FAILURE を 指定した場合、例題がどこかで失敗しても、それ以後の例題を続けて実行し、 失敗したテストの総数を報告します; 出力が抑制されるだけです。

REPORTING_FLAGS
上記のエラー報告に関するフラグ全ての論理和をとったビットマスクです。

「doctest ディレクティブ」を使うと、個々の例題に対してオプションフラグ の設定を変更できます。 doctest ディレクティブは特殊な Python コメント文 として表現され、例題のソースコードの後に続けます:

directive ::= "#" "doctest:" directive_options
directive_options ::= directive_option ("," directive_option)*
directive_option ::= on_or_off directive_option_name
on_or_off ::= "+" | "-"
directive_option_name ::= "DONT_ACCEPT_BLANKLINE" | "NORMALIZE_WHITESPACE" | ...
Download entire grammar as text.

+- とディレクティブオプション名の間に空白を入れては なりません。ディレクティブオプション名は上で説明したオプションフラグ名 のいずれかです。

ある例題の doctest ディレクティブは、その例題だけの doctest の 振る舞いを変えます。ある特定の挙動を有効にしたければ + を、 無効にしたければ - を使います。

例えば、以下のテストはパスします:

>>> print range(20) #doctest: +NORMALIZE_WHITESPACE
[0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
10,  11, 12, 13, 14, 15, 16, 17, 18, 19]

ディレクティブがない場合、実際の出力には一桁の数字の間に二つスペースが 入っていないこと、実際の出力は 1 行になることから、テストはパスしない はずです。別のディレクティブを使って、このテストをパスさせることも できます:

>>> print range(20) # doctest:+ELLIPSIS
[0, 1, ..., 18, 19]

複数のディレクティブは、一つの物理行の中にコンマで区切って指定できます:

>>> print range(20) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[0,    1, ...,   18,    19]

一つの例題中で複数のディレクティブコメントを使った場合、それらは 組み合わされます:

>>> print range(20) # doctest: +ELLIPSIS
...                 # doctest: +NORMALIZE_WHITESPACE
[0,    1, ...,   18,    19]

前の例題で示したように、"..." の後ろにディレクティブだけの 入った行を例題のうしろに追加して書けます。この書きかたは、 例題が長すぎるためにディレクティブを同じ行に入れると収まりが悪い 場合に便利です:

>>> print range(5) + range(10,20) + range(30,40) + range(50,60)
... # doctest: +ELLIPSIS
[0, ..., 4, 10, ..., 19, 30, ..., 39, 50, ..., 59]

デフォルトでは全てのオプションが無効になっており、ディレクティブは 特定の例題だけに影響を及ぼすので、通常意味があるのは有効にするための オプション(+ のついたディレクティブ) だけです。とはいえ、 doctest を実行する関数はオプションフラグを指定してデフォルトとは 異なった挙動を実現できるので、そのような場合には - を使った 無効化オプションも意味を持ちます。

バージョン 2.4 で 変更 された仕様: Constants DONT_ACCEPT_BLANKLINE, NORMALIZE_WHITESPACE, ELLIPSIS, IGNORE_EXCEPTION_DETAIL, REPORT_UDIFF, REPORT_CDIFF, REPORT_NDIFF, REPORT_ONLY_FIRST_FAILURE, COMPARISON_FLAGS and REPORTING_FLAGS を追加しました。予想出力中の <BLANKLINE> がデフォルトで 実際の出力中の空行にマッチするようになりました。また、 doctest ディレクティブが追加されました

新たなオプションフラグ名を登録する方法もありますが、doctest の内部をサブクラスで拡張しない限り、意味はないでしょう:

register_optionflag( name)
名前name の新たなオプションフラグを作成し、作成されたフラグの 整数値を返します。register_optionflag()OutputCheckerDocTestRunner をサブクラス化して、 その中で新たに作成したオプションをサポートさせる際に使います。 register_optionflag は以下のような定形文で呼び出さねば なりません:

  MY_FLAG = register_optionflag('MY_FLAG')

バージョン 2.4 で 新たに追加 された仕様です。

ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。