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
引数を追加しました。