tornado.testing — 非同期コードのユニットテストサポート¶
自動テストのためのサポートクラス。
AsyncTestCaseおよびAsyncHTTPTestCase: unittest.TestCase のサブクラスで、非同期(IOLoopベース)コードのテストのための追加サポートを提供します。ExpectLog: テストログのスパムを減らします。main(): シンプルなテストランナー (unittest.main() のラッパー) で、コード変更時にテストを再実行するための tornado.autoreload モジュールのサポート付き。
非同期テストケース¶
- class tornado.testing.AsyncTestCase(methodName: str = 'runTest')[ソース]¶
TestCaseサブクラスで、IOLoopベースの非同期コードのテスト用です。unittestフレームワークは同期的なので、テストメソッドがリターンするまでにテストが完了している必要があります。これは、非同期コードが通常と同じようには使用できず、適合させる必要があることを意味します。コルーチンでテストを記述するには、テストメソッドを
tornado.gen.coroutineの代わりにtornado.testing.gen_testでデコレートしてください。このクラスは、より手動的なテストスタイルのための (非推奨の)
stop()メソッドとwait()メソッドも提供しています。テストメソッド自体がself.wait()を呼び出し、非同期コールバックが完了を知らせるためにself.stop()を呼び出す必要があります。デフォルトでは、新しい
IOLoopが各テストのために構築され、self.io_loopとして利用可能です。テスト対象のコードが再利用されたグローバルIOLoopを必要とする場合は、サブクラスはそれを返すためにget_new_ioloopをオーバーライドする必要があります。ただし、これは Tornado 6.3 以降非推奨です。IOLoopのstartおよびstopメソッドを直接呼び出すべきではありません。代わりに、self.stopおよびself.waitを使用してください。self.stopに渡される引数は、self.waitから返されます。同じテストで複数のwait/stopサイクルを持つことができます。例
# This test uses coroutine style. class MyTestCase(AsyncTestCase): @tornado.testing.gen_test def test_http_fetch(self): client = AsyncHTTPClient() response = yield client.fetch("https://tornado.dokyumento.jp") # Test contents of response self.assertIn("FriendFeed", response.body) # This test uses argument passing between self.stop and self.wait. class MyTestCase2(AsyncTestCase): def test_http_fetch(self): client = AsyncHTTPClient() client.fetch("https://tornado.dokyumento.jp/", self.stop) response = self.wait() # Test contents of response self.assertIn("FriendFeed", response.body)
- get_new_ioloop() IOLoop[ソース]¶
このテストに使用する
IOLoopを返します。デフォルトでは、新しい
IOLoopが各テスト用に作成されます。サブクラスは、各テストで新しいIOLoopを使用することが適切でない場合 (たとえば、デフォルトのIOLoopを使用するグローバルシングルトンがある場合)、またはテストごとのイベントループが別のシステム (例えば、pytest-asyncio) によって提供されている場合、IOLoop.current()を返すためにこのメソッドをオーバーライドする場合があります。バージョン 6.3 で非推奨: このメソッドは Tornado 7.0 で削除されます。
- stop(_arg: Optional[Any] = None, **kwargs: Any) None[ソース]¶
- wait(condition: Optional[Callable[[...], bool]] = None, timeout: Optional[float] = None) Any[ソース]¶
stop が呼び出されるか、タイムアウトするまで
IOLoopを実行します。タイムアウトが発生した場合、例外がスローされます。デフォルトのタイムアウトは 5 秒です。これは、
timeoutキーワード引数で上書きするか、グローバルにASYNC_TEST_TIMEOUT環境変数で上書きできます。conditionがNoneでない場合、IOLoopは、stop()の後、condition()がTrueを返すまで再起動されます。バージョン 3.1 で変更:
ASYNC_TEST_TIMEOUT環境変数が追加されました。
- class tornado.testing.AsyncHTTPTestCase(methodName: str = 'runTest')[ソース]¶
HTTP サーバーを起動するテストケース。
サブクラスは、テスト対象の
tornado.web.Application(またはその他のHTTPServerコールバック) を返すget_app()をオーバーライドする必要があります。テストでは通常、提供されているself.http_clientを使用して、このサーバーから URL をフェッチします。例:ユーザーガイドの「Hello, world」の例が
hello.pyにあると仮定します。import hello class TestHelloApp(AsyncHTTPTestCase): def get_app(self): return hello.make_app() def test_homepage(self): response = self.fetch('/') self.assertEqual(response.code, 200) self.assertEqual(response.body, 'Hello, world')
self.fetch()の呼び出しは、以下と同等です。self.http_client.fetch(self.get_url('/'), self.stop) response = self.wait()
これは、AsyncTestCase が
http_client.fetch()のような非同期操作を同期操作に変換する方法を示しています。テストで他の非同期操作を行う必要がある場合は、おそらくstop()とwait()を自分で使用する必要があります。- get_app() Application[ソース]¶
サブクラスは、
tornado.web.Applicationまたはその他のHTTPServerコールバックを返すようにオーバーライドする必要があります。
- fetch(path: str, raise_error: bool = False, **kwargs: Any) HTTPResponse[ソース]¶
URL を同期的にフェッチするための便利なメソッド。
指定されたパスは、ローカルサーバーのホストとポートに追加されます。追加のキーワード引数は、
AsyncHTTPClient.fetchに直接渡されます(そのため、method="POST"、body="..."などを渡すために使用できます)。パスが http:// または https:// で始まる場合、完全な URL として扱われ、そのままフェッチされます。
raise_errorがTrueの場合、応答コードが 200 でない場合は、tornado.httpclient.HTTPErrorが発生します。これは、AsyncHTTPClient.fetchのraise_error引数と同じ動作ですが、ここではデフォルトがFalseです(AsyncHTTPClientではTrueです)。テストでは、200 以外の応答コードを処理する必要がある場合が多いためです。バージョン 5.0 で変更: 絶対 URL のサポートが追加されました。
バージョン 5.1 で変更:
raise_error引数が追加されました。バージョン 5.1 で非推奨: このメソッドは現在、任意の例外をステータスコード 599 の
HTTPResponseに変換します。Tornado 6.0 では、tornado.httpclient.HTTPError以外のエラーはそのまま渡され、raise_error=Falseは 200 以外の応答コードのために発生するエラーのみを抑制します。
- class tornado.testing.AsyncHTTPSTestCase(methodName: str = 'runTest')[ソース]¶
HTTPS サーバーを起動するテストケース。
インターフェイスは、一般的に
AsyncHTTPTestCaseと同じです。
- tornado.testing.gen_test(*, timeout: Optional[float] = None) Callable[[Callable[[...], Union[Generator, Coroutine]]], Callable[[...], None]][ソース]¶
- tornado.testing.gen_test(func: Callable[[...], Union[Generator, Coroutine]]) Callable[[...], None]
@gen.coroutineと同等のテスト用デコレータで、テストメソッドに適用します。IOLoopがまだ実行されていないため、テストで@gen.coroutineを使用することはできません。@gen_testはAsyncTestCaseのサブクラスのテストメソッドに適用する必要があります。例
class MyTest(AsyncHTTPTestCase): @gen_test def test_something(self): response = yield self.http_client.fetch(self.get_url('/'))
デフォルトでは、
@gen_testは5秒後にタイムアウトします。タイムアウトは、環境変数ASYNC_TEST_TIMEOUTでグローバルにオーバーライドするか、timeoutキーワード引数でテストごとにオーバーライドできます。class MyTest(AsyncHTTPTestCase): @gen_test(timeout=10) def test_something_slow(self): response = yield self.http_client.fetch(self.get_url('/'))
@gen_testはAsyncTestCase.stop、AsyncTestCase.wait、およびAsyncHTTPTestCase.fetchと互換性がないことに注意してください。代わりに、上記のようにyield self.http_client.fetch(self.get_url())を使用してください。バージョン 3.1 で追加:
timeout引数とASYNC_TEST_TIMEOUT環境変数。バージョン 4.0 で変更: ラッパーは
*args, **kwargsを渡すようになり、引数を持つ関数でも使用できるようになりました。
ログ出力の制御¶
- class tornado.testing.ExpectLog(logger: Union[Logger, str], regex: str, required: bool = True, level: Optional[int] = None)[ソース]¶
予期されるログ出力をキャプチャして抑制するためのコンテキストマネージャー。
エラー条件のテストをノイズレスにしつつ、予期しないログエントリを表示したままにするのに役立ちます。スレッドセーフではありません。
例外スタックトレースがログに記録された場合、属性
logged_stackはTrueに設定されます。使用方法
with ExpectLog('tornado.application', "Uncaught exception"): error_response = self.fetch("/some_page")
バージョン 4.3 で変更:
logged_stack属性が追加されました。ExpectLog コンテキストマネージャーを構築します。
- パラメータ
logger – 監視するロガーオブジェクト(またはロガーの名前)。ルートロガーを監視するには、空の文字列を渡します。
regex – 一致させる正規表現。指定されたロガーのログエントリで、この正規表現に一致するものは抑制されます。
required – true の場合、ログエントリが一致せずに
withステートメントの終わりに達すると、例外が発生します。level – 予期されるログレベルを示す
loggingモジュールの定数。このパラメータが指定されている場合、このレベルのログメッセージのみが一致するとみなされます。さらに、指定されたloggerは、予期されるメッセージを有効にするために、ExpectLogの期間中、必要に応じてそのレベルが調整されます。
バージョン 6.1 で変更:
levelパラメータが追加されました。バージョン 6.3 で非推奨: Tornado 7.0 では、デフォルトで
WARNING以上のログレベルのみが一致するようになります。INFO以下のレベルに一致させるには、level引数を使用する必要があります。これは、tornado.testing.main(デフォルトでINFOログを有効にします)と、デフォルトでINFOログが無効になっている IDE のものを含むほとんどの他のテストランナーとの違いを最小限に抑えるための変更です。
テストランナー¶
- tornado.testing.main(**kwargs: Any) None[ソース]¶
シンプルなテストランナー。
このテストランナーは、標準ライブラリの
unittest.mainとほぼ同等ですが、Tornado スタイルのオプション解析とログフォーマットのサポートが追加されています。このmain関数を使用しなくても、AsyncTestCaseを使用してテストを実行することはできます。これらのテストは自己完結型であり、どのテストランナーでも実行できます。テストを実行する最も簡単な方法は、コマンドラインを使用することです。
python -m tornado.testing tornado.test.web_test
テストを指定する方法については、標準ライブラリの
unittestモジュールを参照してください。多くのテストを含むプロジェクトでは、
tornado/test/runtests.pyのようなテストスクリプトを定義することが推奨されます。このスクリプトは、テストスイートを返すall()メソッドを定義し、その後tornado.testing.main()を呼び出す必要があります。テストスクリプトが使用されている場合でも、コマンドラインで単一のテストを指定することでall()テストスイートを上書きできることに注意してください。# Runs all tests python -m tornado.test.runtests # Runs one test python -m tornado.test.runtests tornado.test.web_test
unittest.main()に渡される追加のキーワード引数。たとえば、tornado.testing.main(verbosity=2)を使用すると、実行中のテストの詳細が多数表示されます。引数の完全なリストについては、http://docs.python.org/library/unittest.html#unittest.main を参照してください。バージョン 5.0 で変更: この関数は、
unittestモジュールによって生成されたもの以外は、独自の出力を生成しません(以前は PASS または FAIL のログメッセージを追加していました)。
ヘルパー関数¶
- tornado.testing.bind_unused_port(reuse_port: bool = False, address: str = '127.0.0.1') Tuple[socket, int][ソース]¶
サーバーソケットを localhost の利用可能なポートにバインドします。
タプル (ソケット, ポート) を返します。
バージョン 4.4 で変更: 常に
localhostという名前を解決せずに127.0.0.1にバインドします。バージョン 6.2 で変更: デフォルトの "127.0.0.1" をオーバーライドするためのオプションの
address引数を追加しました。