26.8。 テスト —Python用の回帰テストパッケージ
ノート
test パッケージは、Pythonによる内部使用のみを目的としています。 Pythonのコア開発者のために文書化されています。 ここに記載されているコードは、Pythonのリリース間で予告なしに変更または削除される可能性があるため、Pythonの標準ライブラリの外部でこのパッケージを使用することはお勧めしません。
test パッケージには、Pythonのすべての回帰テストと、モジュール test.support およびtest.regrtest
が含まれています。 test.support はテストを強化するために使用され、test.regrtest
はテストスイートを駆動します。
名前がtest_
で始まる test パッケージの各モジュールは、特定のモジュールまたは機能のテストスイートです。 すべての新しいテストは、 unittest または doctest モジュールを使用して作成する必要があります。 一部の古いテストは、sys.stdout
に出力された出力を比較する「従来の」テストスタイルを使用して記述されています。 このスタイルのテストは非推奨と見なされます。
26.8.1。 のユニットテストの作成テストパッケージ
unittest モジュールを使用するテストはいくつかのガイドラインに従うことが望ましいです。 1つは、test_
で開始してテストモジュールに名前を付け、テストするモジュールの名前で終了することです。 テストモジュールのテストメソッドは、test_
で始まり、メソッドがテストしている内容の説明で終わる必要があります。 これは、メソッドがテストドライバーによってテストメソッドとして認識されるために必要です。 また、メソッドのドキュメント文字列を含めることはできません。 コメント(# Tests function returns only True or False
など)を使用して、テストメソッドのドキュメントを提供する必要があります。 これが行われるのは、ドキュメント文字列が存在する場合は印刷され、実行されているテストが指定されていないためです。
基本的な定型文がよく使用されます。
このコードパターンにより、テストスイートをtest.regrtest
で実行したり、 unittest CLIをサポートするスクリプトとして単独で実行したり、python -m unittest
CLIを介して実行したりできます。
回帰テストの目標は、コードを解読しようとすることです。 これにより、従うべきいくつかのガイドラインが導き出されます。
テストスイートは、すべてのクラス、関数、および定数を実行する必要があります。 これには、外部に提示される外部APIだけでなく、「プライベート」コードも含まれます。
ホワイトボックステスト(テストの作成時にテストされるコードを調べる)が推奨されます。 ブラックボックステスト(公開されたユーザーインターフェイスのみをテストする)は、すべての境界およびエッジケースがテストされていることを確認するのに十分なほど完全ではありません。
無効な値を含め、すべての可能な値がテストされていることを確認してください。 これにより、すべての有効な値が受け入れられるだけでなく、不適切な値が正しく処理されるようになります。
できるだけ多くのコードパスを使い果たします。 分岐が発生する場所をテストし、入力を調整して、コード内でできるだけ多くの異なるパスが使用されることを確認します。
テストされたコードで発見されたバグの明示的なテストを追加します。 これにより、将来コードが変更された場合にエラーが再発しないようになります。
テスト後は必ずクリーンアップしてください(すべての一時ファイルを閉じて削除するなど)。
テストがオペレーティングシステムの特定の条件に依存している場合は、テストを試行する前に、条件がすでに存在することを確認してください。
できるだけ少ないモジュールをインポートし、できるだけ早く実行します。 これにより、テストの外部依存関係が最小限に抑えられ、モジュールのインポートの副作用による異常な動作の可能性も最小限に抑えられます。
コードの再利用を最大化するようにしてください。 場合によっては、使用される入力のタイプと同じくらい小さいものによってテストが異なることがあります。 基本的なテストクラスを入力を指定するクラスでサブクラス化することにより、コードの重複を最小限に抑えます。
このパターンを使用するときは、 unittest.TestCase から継承するすべてのクラスがテストとして実行されることに注意してください。 上記の例の
Mixin
クラスにはデータがないため、単独で実行することはできません。したがって、 unittest.TestCase から継承しません。
も参照してください
- テスト駆動開発
- コードの前にテストを書くことに関するケントベックの本。
26.8.2。 コマンドラインインターフェイスを使用したテストの実行
test パッケージは、 -m オプション python -m test のおかげで、Pythonの回帰テストスイートを駆動するスクリプトとして実行できます。 内部では、test.regrtest
を使用します。 以前のPythonバージョンで使用されていた python -m test.regrtest の呼び出しは引き続き機能します。 スクリプトを単独で実行すると、 test パッケージ内のすべての回帰テストの実行が自動的に開始されます。 これは、名前がtest_
で始まるパッケージ内のすべてのモジュールを検索してインポートし、存在する場合は関数test_main()
を実行するか、test_main
は存在しません。 実行するテストの名前もスクリプトに渡される場合があります。 単一の回帰テスト( python -m test test_spam )を指定すると、出力が最小化され、テストが成功したか失敗したかのみが出力されます。
test を直接実行すると、テストに使用できるリソースを直接設定できます。 これを行うには、-u
コマンドラインオプションを使用します。 -u
オプションの値としてall
を指定すると、すべての可能なリソースが有効になります: python -m test -uall 。 1つを除くすべてのリソースが必要な場合(より一般的なケース)、不要なリソースのコンマ区切りリストがall
の後にリストされる場合があります。 コマンド python -m test -uall、-audio、-largefile は、audio
およびlargefile
リソースを除くすべてのリソースで test を実行します。 すべてのリソースとその他のコマンドラインオプションのリストについては、 python -m test -h を実行してください。
回帰テストを実行する他のいくつかの方法は、テストが実行されているプラットフォームによって異なります。 Unixでは、Pythonが構築された最上位ディレクトリで make test を実行できます。 Windowsでは、PCBuild
ディレクトリから rt.bat を実行すると、すべての回帰テストが実行されます。
26.9。 test.support —Pythonテストスイートのユーティリティ
test.support モジュールは、Pythonの回帰テストスイートのサポートを提供します。
ノート
test.support はパブリックモジュールではありません。 Python開発者がテストを作成するのに役立つように、ここに文書化されています。 このモジュールのAPIは、リリース間の下位互換性の懸念なしに変更される可能性があります。
このモジュールは、次の例外を定義します。
- exception test.support.TestFailed
- テストが失敗したときに発生する例外。 これは、 unittest ベースのテストと unittest.TestCase のアサーションメソッドを優先して非推奨になりました。
- exception test.support.ResourceDenied
- unittest.SkipTest のサブクラス。 リソース(ネットワーク接続など)が利用できない場合に発生します。 require()関数によって発生します。
test.support モジュールは、次の定数を定義します。
- test.support.verbose
True
詳細出力が有効な場合。 実行中のテストについてより詳細な情報が必要な場合は、チェックする必要があります。 verbose はtest.regrtest
によって設定されます。
- test.support.is_jython
True
実行中のインタープリターがJythonの場合。
- test.support.TESTFN
- 一時ファイルの名前として安全に使用できる名前に設定します。 作成された一時ファイルはすべて閉じて、リンクを解除(削除)する必要があります。
test.support モジュールは、次の関数を定義します。
- test.support.forget(module_name)
- module_name という名前のモジュールを
sys.modules
から削除し、モジュールのバイトコンパイルされたファイルをすべて削除します。
- test.support.is_resource_enabled(resource)
- リソースが有効で使用可能な場合は、
True
を返します。 利用可能なリソースのリストは、test.regrtest
がテストを実行しているときにのみ設定されます。
- test.support.requires(resource, msg=None)
- リソースが利用できない場合は、 ResourceDenied を上げます。 msg は、 ResourceDenied が発生した場合の引数です。
__name__
が'__main__'
である関数によって呼び出された場合、常にTrue
を返します。test.regrtest
でテストを実行する場合に使用します。
- test.support.findfile(filename, subdir=None)
filename という名前のファイルへのパスを返します。 一致するものが見つからない場合は、ファイル名が返されます。 これはファイルへのパスである可能性があるため、失敗と同じではありません。
subdir を設定すると、パスディレクトリを直接調べるのではなく、ファイルを見つけるために使用する相対パスが示されます。
- test.support.run_unittest(\*classes)
関数に渡された unittest.TestCase サブクラスを実行します。 この関数は、プレフィックス
test_
で始まるメソッドのクラスをスキャンし、テストを個別に実行します。文字列をパラメータとして渡すことも合法です。 これらは
sys.modules
のキーである必要があります。 関連する各モジュールは、unittest.TestLoader.loadTestsFromModule()
によってスキャンされます。 これは通常、次のtest_main()
関数で見られます。これにより、指定されたモジュールで定義されたすべてのテストが実行されます。
- test.support.run_doctest(module, verbosity=None)
指定されたモジュールで doctest.testmod()を実行します。
(failure_count, test_count)
を返します。verbosity が
None
の場合、 doctest.testmod()は、vervosityを verbose に設定して実行されます。 それ以外の場合は、詳細度をNone
に設定して実行されます。
- test.support.check_warnings(\*filters, quiet=True)
warnings.catch_warnings()の便利なラッパーで、警告が正しく発生したことを簡単にテストできます。 これは、 warnings.simplefilter()を
always
に設定し、記録された結果を自動的に検証するオプションを指定してwarnings.catch_warnings(record=True)
を呼び出すのとほぼ同じです。check_warnings
は、位置引数として("message regexp", WarningCategory)
の形式の2タプルを受け入れます。 1つ以上の filters が提供されている場合、またはオプションのキーワード引数 quick がFalse
の場合、警告が期待どおりであることを確認します。指定された各フィルターは必須です。同封のコードによって発生した警告の少なくとも1つに一致するか、テストが失敗し、指定されたフィルターのいずれにも一致しない警告が発生した場合、テストは失敗します。 これらの最初のチェックを無効にするには、 quick をTrue
に設定します。引数が指定されていない場合、デフォルトで次のようになります。
この場合、すべての警告がキャッチされ、エラーは発生しません。
コンテキストマネージャーに入ると、
WarningRecorder
インスタンスが返されます。 catch_warnings()の基になる警告リストは、レコーダーオブジェクトの warnings 属性を介して利用できます。 便宜上、最新の警告を表すオブジェクトの属性には、レコーダーオブジェクトから直接アクセスすることもできます(以下の例を参照)。 警告が発生していない場合、警告を表すオブジェクトで予期される属性はすべてNone
を返します。レコーダオブジェクトには、警告リストをクリアする
reset()
メソッドもあります。コンテキストマネージャーは、次のように使用するように設計されています。
この場合、警告が発生しなかった場合、またはその他の警告が発生した場合、 check_warnings()はエラーを発生させます。
テストで警告が発生したかどうかを確認するだけでなく、警告をより深く調べる必要がある場合は、次のようなコードを使用できます。
ここですべての警告がキャッチされ、テストコードはキャプチャされた警告を直接テストします。
バージョン3.2で変更:新しいオプションの引数フィルターおよびクワイエット。
- test.support.captured_stdin()
test.support.captured_stdout()
test.support.captured_stderr() 名前付きストリームを io.StringIO オブジェクトに一時的に置き換えるコンテキストマネージャー。
出力ストリームでの使用例:
入力ストリームでの使用例:
- test.support.temp_dir(path=None, quiet=False)
path に一時ディレクトリを作成し、そのディレクトリを生成するコンテキストマネージャ。
path が
None
の場合、一時ディレクトリは tempfile.mkdtemp()を使用して作成されます。 quick がFalse
の場合、コンテキストマネージャーはエラー時に例外を発生させます。 それ以外の場合、パスが指定されていて作成できない場合は、警告のみが発行されます。
- test.support.change_cwd(path, quiet=False)
現在の作業ディレクトリをパスに一時的に変更し、ディレクトリを生成するコンテキストマネージャ。
quick が
False
の場合、コンテキストマネージャーはエラー時に例外を発生させます。 それ以外の場合は、警告のみを発行し、現在の作業ディレクトリを同じに保ちます。
- test.support.temp_cwd(name='tempcwd', quiet=False)
新しいディレクトリを一時的に作成し、現在の作業ディレクトリ(CWD)を変更するコンテキストマネージャ。
コンテキストマネージャは、現在の作業ディレクトリを一時的に変更する前に、 name という名前で現在のディレクトリに一時ディレクトリを作成します。 name が
None
の場合、一時ディレクトリは tempfile.mkdtemp()を使用して作成されます。quiet が
False
であり、CWDを作成または変更できない場合、エラーが発生します。 それ以外の場合は、警告のみが発生し、元のCWDが使用されます。
- test.support.temp_umask(umask)
- プロセスのumaskを一時的に設定するコンテキストマネージャー。
- test.support.can_symlink()
- OSがシンボリックリンクをサポートしている場合は
True
を返し、そうでない場合はFalse
を返します。
- @test.support.skip_unless_symlink
- シンボリックリンクのサポートを必要とするテストを実行するためのデコレータ。
- @test.support.anticipate_failure(condition)
- unittest.expectedFailure()でテストを条件付きでマークするデコレータ。 このデコレータを使用する場合は、関連するトラッカーの問題を特定するコメントを関連付ける必要があります。
- @test.support.run_with_locale(catstr, *locales)
- 別のロケールで関数を実行するためのデコレータ。終了後に関数を正しくリセットします。 catstr は、文字列としてのロケールカテゴリです(たとえば、
"LC_ALL"
)。 渡された locales が順番に試行され、最初の有効なロケールが使用されます。
- test.support.make_bad_fd()
- 一時ファイルを開いたり閉じたりして、その記述子を返すことにより、無効なファイル記述子を作成します。
- test.support.import_module(name, deprecated=False)
この関数は、指定されたモジュールをインポートして返します。 通常のインポートとは異なり、この関数は、モジュールをインポートできない場合に unittest.SkipTest を発生させます。
deprecated が
True
の場合、モジュールとパッケージの非推奨メッセージはこのインポート中に抑制されます。バージョン3.1の新機能。
- test.support.import_fresh_module(name, fresh=(), blocked=(), deprecated=False)
この関数は、インポートを実行する前に
sys.modules
から名前付きモジュールを削除することにより、名前付きPythonモジュールの新しいコピーをインポートして返します。reload()
とは異なり、元のモジュールはこの操作の影響を受けないことに注意してください。fresh は、インポートを実行する前に
sys.modules
キャッシュからも削除される追加のモジュール名の反復可能です。blocked は、インポート中にモジュールキャッシュ内で
None
に置き換えられるモジュール名の反復可能であり、それらをインポートしようとすると ImportError が発生します。指定されたモジュールと、 fresh および blocked パラメーターで指定されたモジュールは、インポートを開始する前に保存され、新規インポートが完了すると
sys.modules
に再挿入されます。deprecated が
True
の場合、モジュールとパッケージの非推奨メッセージはこのインポート中に抑制されます。指定されたモジュールをインポートできない場合、この関数は ImportError を発生させます。
使用例:
バージョン3.1の新機能。
- test.support.bind_port(sock, host=HOST)
ソケットを空きポートにバインドし、ポート番号を返します。 バインドされていないポートを使用していることを確認するために、エフェメラルポートに依存しています。 特にビルドボット環境では、多くのテストが同時に実行される可能性があるため、これは重要です。 このメソッドは、
sock.family
が AF_INET で、sock.type
が SOCK_STREAM であり、ソケットにSO_REUSEADDR
またはSO_REUSEPORT
が設定されています。 テストでは、TCP / IPソケットにこれらのソケットオプションを設定しないでください。 これらのオプションを設定する唯一のケースは、複数のUDPソケットを介したマルチキャストのテストです。さらに、
SO_EXCLUSIVEADDRUSE
ソケットオプションが利用可能な場合(つまり、 Windowsの場合)、ソケットに設定されます。 これにより、テスト期間中、他の人がホスト/ポートにバインドするのを防ぐことができます。
- test.support.find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM)
バインドに適しているはずの未使用のポートを返します。 これは、
sock
パラメーター(デフォルトは AF_INET 、 SOCK_STREAM )と同じファミリーとタイプの一時ソケットを作成し、それを指定されたホストにバインドすることで実現されます。ポートを0に設定したアドレス(デフォルトは0.0.0.0
)で、OSから未使用のエフェメラルポートを引き出します。 その後、一時ソケットが閉じられて削除され、エフェメラルポートが返されます。このメソッドまたは bind_port()は、テスト中にサーバーソケットを特定のポートにバインドする必要があるすべてのテストに使用する必要があります。 どちらを使用するかは、呼び出し元のコードがPythonソケットを作成しているかどうか、または未使用のポートをコンストラクターで提供する必要があるか、外部プログラムに渡す必要があるかによって異なります(つまり、 opensslのs_serverモードに対する
-accept
引数)。 可能な場合は、 find_unused_port()よりも bind_port()を常に優先します。 ハードコードされたポートを使用すると、テストの複数のインスタンスを同時に実行できなくなる可能性があるため、お勧めしません。これは、ビルドボットの問題です。
- test.support.load_package_tests(pkg_dir, loader, standard_tests, pattern)
テストパッケージで使用するための unittest
load_tests
プロトコルの汎用実装。 pkg_dir はパッケージのルートディレクトリです。 ローダー、 standard_tests 、およびパターンは、load_tests
で予期される引数です。 単純なケースでは、テストパッケージの__init__.py
は次のようになります。
- test.support.detect_api_mismatch(ref_api, other_api, *, ignore=())
ignore で指定されたこのチェックで無視される項目の定義済みリストを除いて、 other_api で見つからない ref_api の属性、関数、またはメソッドのセットを返します。 。
デフォルトでは、これは「_」で始まるプライベート属性をスキップしますが、すべてのマジックメソッドが含まれます。 '__'で始まり '__'で終わるもの。
バージョン3.5の新機能。
- test.support.check__all__(test_case, module, name_of_module=None, extra=(), blacklist=())
module の
__all__
変数にすべてのパブリック名が含まれていることを表明します。モジュールのパブリック名(そのAPI)は、パブリック名の規則に一致し、モジュールで定義されているかどうかに基づいて自動的に検出されます。
name_of_module 引数は、パブリックAPIとして検出されるためにAPIを定義できるモジュールを(文字列またはそのタプルとして)指定できます。 この1つのケースは、 module がパブリックAPIの一部を他のモジュール(おそらくCバックエンド(
csv
やその_csv
など)からインポートする場合)です。extra 引数は、適切な
__module__
属性のないオブジェクトのように、他の方法では「パブリック」として自動的に検出されない名前のセットにすることができます。 提供されている場合は、自動的に検出されたものに追加されます。blacklist 引数は、名前が別の方法で示している場合でも、パブリックAPIの一部として扱われてはならない名前のセットにすることができます。
使用例:
バージョン3.6の新機能。
test.support モジュールは、次のクラスを定義します。
- class test.support.TransientResource(exc, **kwargs)
- インスタンスは、指定された例外タイプが発生した場合に ResourceDenied を発生させるコンテキストマネージャーです。 キーワード引数はすべて、 with ステートメント内で発生した例外と比較される属性/値ペアとして扱われます。 すべてのペアが例外の属性と適切に一致する場合にのみ、 ResourceDenied が発生します。
- class test.support.EnvironmentVarGuard
環境変数を一時的に設定または設定解除するために使用されるクラス。 インスタンスはコンテキストマネージャーとして使用でき、基になる
os.environ
をクエリ/変更するための完全な辞書インターフェイスを備えています。 コンテキストマネージャーを終了すると、このインスタンスを介して行われた環境変数へのすべての変更がロールバックされます。バージョン3.1で変更:辞書インターフェースを追加。
- EnvironmentVarGuard.set(envvar, value)
- 環境変数
envvar
を一時的にvalue
の値に設定します。
- EnvironmentVarGuard.unset(envvar)
- 環境変数
envvar
の設定を一時的に解除します。
- class test.support.SuppressCrashReport
サブプロセスのクラッシュが予想されるテストでのクラッシュダイアログポップアップの防止を試みるために使用されるコンテキストマネージャー。
Windowsでは、 SetErrorMode を使用してWindowsエラー報告ダイアログを無効にします。
UNIXでは、 resource.setrlimit()を使用して resource.RLIMIT_CORE のソフト制限を0に設定し、コアダンプファイルが作成されないようにします。
どちらのプラットフォームでも、古い値は
__exit__()
によって復元されます。
- class test.support.WarningsRecorder
- 単体テストの警告を記録するために使用されるクラス。 詳細については、上記の check_warnings()のドキュメントを参照してください。
- class test.support.FakePath(path)
- 単純なパスのようなオブジェクト。 path 引数を返すだけの
__fspath__()
メソッドを実装します。 path が例外の場合、__fspath__()
で発生します。