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 以降非推奨です。

IOLoopstart および 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[ソース]

IOLoop を停止させ、保留中の (または将来の) wait() の呼び出しが1つリターンするようにします。

stop() に渡されたキーワード引数または単一の位置引数は保存され、wait() によって返されます。

バージョン 5.1 で非推奨: stopwait は非推奨です。代わりに @gen_test を使用してください。

wait(condition: Optional[Callable[[...], bool]] = None, timeout: Optional[float] = None) Any[ソース]

stop が呼び出されるか、タイムアウトするまで IOLoop を実行します。

タイムアウトが発生した場合、例外がスローされます。デフォルトのタイムアウトは 5 秒です。これは、timeout キーワード引数で上書きするか、グローバルに ASYNC_TEST_TIMEOUT 環境変数で上書きできます。

conditionNone でない場合、IOLoop は、stop() の後、condition()True を返すまで再起動されます。

バージョン 3.1 で変更: ASYNC_TEST_TIMEOUT 環境変数が追加されました。

バージョン 5.1 で非推奨: stopwait は非推奨です。代わりに @gen_test を使用してください。

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_errorTrue の場合、応答コードが 200 でない場合は、tornado.httpclient.HTTPError が発生します。これは、AsyncHTTPClient.fetchraise_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 以外の応答コードのために発生するエラーのみを抑制します。

get_httpserver_options() Dict[str, Any][ソース]

サブクラスによってオーバーライドされて、サーバーの追加のキーワード引数を返す場合があります。

get_http_port() int[ソース]

サーバーが使用するポートを返します。

新しいポートは、各テストで選択されます。

get_url(path: str) str[ソース]

テストサーバー上の指定されたパスに対する絶対 URL を返します。

class tornado.testing.AsyncHTTPSTestCase(methodName: str = 'runTest')[ソース]

HTTPS サーバーを起動するテストケース。

インターフェイスは、一般的に AsyncHTTPTestCase と同じです。

get_ssl_options() Dict[str, Any][ソース]

サブクラスによってオーバーライドされて、SSL オプションを選択する場合があります。

デフォルトでは、自己署名テスト証明書が含まれています。

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_testAsyncTestCase のサブクラスのテストメソッドに適用する必要があります。

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_testAsyncTestCase.stopAsyncTestCase.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_stackTrue に設定されます。

使用方法

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

tornado.testing.get_async_test_timeout() float[ソース]

非同期テストのグローバルタイムアウト設定を取得します。

秒単位のタイムアウトを表す float を返します。

バージョン 3.1 で新規追加。