Flaskアプリケーションのテスト
テストされていないものが壊れています。
この引用の出所は不明であり、完全に正しいわけではありませんが、真実からそう遠くはありません。 テストされていないアプリケーションは既存のコードを改善することを困難にし、テストされていないアプリケーションの開発者はかなり妄想的になる傾向があります。 アプリケーションに自動テストがある場合は、安全に変更を加えて、何かが壊れているかどうかを即座に知ることができます。
Flaskは、WerkzeugテストClient
を公開し、コンテキストローカルを処理することで、アプリケーションをテストする方法を提供します。 その後、お気に入りのテストソリューションでそれを使用できます。
このドキュメントでは、テストの基本フレームワークとして pytest パッケージを使用します。 次のように、pip
を使用してインストールできます。
アプリケーション
まず、テストするアプリケーションが必要です。 チュートリアルのアプリケーションを使用します。 そのアプリケーションをまだお持ちでない場合は、からソースコードを入手してください :gh: `例 ` 。
テストスケルトン
まず、アプリケーションルートの下にtestsディレクトリを追加します。 次に、テストを保存するPythonファイル(test_flaskr.py
)を作成します。 test_*.py
のようにファイル名をフォーマットすると、pytestによって自動検出されます。
次に、client()
という pytestフィクスチャを作成します。これは、アプリケーションをテスト用に構成し、新しいデータベースを初期化します。
このクライアントフィクスチャは、個々のテストごとに呼び出されます。 これにより、アプリケーションへのシンプルなインターフェイスが提供され、アプリケーションへのテストリクエストをトリガーできます。 クライアントはまた、私たちのためにクッキーを追跡します。
セットアップ中に、TESTING
構成フラグがアクティブになります。 これにより、リクエスト処理中のエラーキャッチが無効になり、アプリケーションに対してテストリクエストを実行する際のエラーレポートが改善されます。
SQLite3はファイルシステムベースであるため、tempfile
モジュールを使用して一時データベースを簡単に作成して初期化できます。 mkstemp()
関数は、低レベルのファイルハンドルとランダムなファイル名を返します。後者はデータベース名として使用します。 os.close()
関数を使用してファイルを閉じることができるように、 db_fd を保持する必要があります。
テスト後にデータベースを削除するには、フィクスチャはファイルを閉じてファイルシステムから削除します。
ここでテストスイートを実行すると、次の出力が表示されます。
実際のテストは実行されませんでしたが、flaskr
アプリケーションが構文的に有効であることがすでにわかっています。そうでない場合、インポートは例外で終了します。
最初のテスト
次に、アプリケーションの機能のテストを開始します。 アプリケーションのルート(/
)にアクセスした場合、アプリケーションに「これまでのところエントリがありません」と表示されていることを確認しましょう。 これを行うには、次のような新しいテスト関数をtest_flaskr.py
に追加します。
テスト関数が test という単語で始まることに注意してください。 これにより、 pytest は、実行するテストとして関数を自動的に識別できます。
client.get
を使用することで、HTTP GET
リクエストを指定されたパスでアプリケーションに送信できます。 戻り値はresponse_class
オブジェクトになります。 これで、data
属性を使用して、アプリケーションからの戻り値(文字列として)を検査できます。 この場合、'No entries here so far'
が出力の一部であることを確認します。
もう一度実行すると、1つの合格テストが表示されます。
ログインとログアウト
アプリケーションの機能の大部分は管理ユーザーのみが利用できるため、テストクライアントをアプリケーションにログインおよびログアウトする方法が必要です。 これを行うために、必要なフォームデータ(ユーザー名とパスワード)を使用して、ログインページとログアウトページにいくつかのリクエストを送信します。 また、ログインページとログアウトページがリダイレクトされるため、クライアントに follow_redirects を指示します。
次の2つの関数をtest_flaskr.py
ファイルに追加します。
これで、ログインとログアウトが機能し、無効な資格情報で失敗することを簡単にテストできます。 この新しいテスト関数を追加します。
メッセージの追加をテストする
また、メッセージの追加が機能することをテストする必要があります。 次のような新しいテスト関数を追加します。
ここでは、HTMLがテキストで許可されているが、タイトルでは許可されていないことを確認します。これは意図された動作です。
これを実行すると、3つの合格テストが得られるはずです。
その他のテストのコツ
上記のようにテストクライアントを使用する以外に、test_request_context()
メソッドをwith
ステートメントと組み合わせて使用して、要求コンテキストを一時的にアクティブ化することもできます。 これにより、ビュー関数のように request 、 g 、および session オブジェクトにアクセスできます。 このアプローチを示す完全な例を次に示します。
コンテキストにバインドされている他のすべてのオブジェクトは、同じ方法で使用できます。
さまざまな構成でアプリケーションをテストする必要があり、それを行うための適切な方法がないように思われる場合は、アプリケーションファクトリに切り替えることを検討してください(アプリケーションファクトリを参照)。
ただし、テスト要求コンテキストを使用している場合、before_request()
およびafter_request()
関数は自動的に呼び出されないことに注意してください。 ただし、teardown_request()
関数は、テスト要求コンテキストがwith
ブロックを離れるときに実際に実行されます。 before_request()
関数も呼び出す場合は、preprocess_request()
を自分で呼び出す必要があります。
これは、アプリケーションの設計方法によっては、データベース接続などを開くために必要になる場合があります。
after_request()
関数を呼び出す場合は、process_response()
を呼び出す必要がありますが、応答オブジェクトを渡す必要があります。
その時点でテストクライアントの使用を直接開始できるため、これは一般的にあまり役に立ちません。
偽のリソースとコンテキスト
バージョン0.10の新機能。
非常に一般的なパターンは、ユーザー認証情報とデータベース接続をアプリケーションコンテキストまたは flask.g オブジェクトに保存することです。 このための一般的なパターンは、最初の使用時にオブジェクトをそこに配置し、次に分解時にオブジェクトを削除することです。 たとえば、現在のユーザーを取得する次のコードを想像してみてください。
テストの場合、コードを変更せずに、このユーザーを外部からオーバーライドすると便利です。 これは、 flask.appcontext_pushed 信号をフックすることで実現できます。
そしてそれを使用するには:
コンテキストを維持する
バージョン0.4の新機能。
定期的なリクエストをトリガーしても、コンテキストをもう少し長く維持して、追加のイントロスペクションが発生するようにすると便利な場合があります。 Flask 0.4では、test_client()
とwith
ブロックを使用することでこれが可能です。
with
ブロックなしでtest_client()
のみを使用すると、リクエストが使用できなくなったため、assert
はエラーで失敗します(実際のリクエストの範囲外で使用しようとしています)。
セッションへのアクセスと変更
バージョン0.8の新機能。
テストクライアントからセッションにアクセスまたは変更すると非常に役立つ場合があります。 一般に、これには2つの方法があります。 セッションで特定のキーが特定の値に設定されていることを確認したいだけの場合は、コンテキストを維持して flask.session にアクセスできます。
ただし、これでは、要求が発生する前にセッションを変更したり、セッションにアクセスしたりすることはできません。 Flask 0.8から、テストクライアントのコンテキストでセッションを開き、それを変更するための適切な呼び出しをシミュレートする、いわゆる「セッショントランザクション」を提供します。 トランザクションの終了時に、セッションが保存され、テストクライアントで使用できるようになります。 これは、使用されるセッションバックエンドとは独立して機能します。
この場合、 Flask.session プロキシの代わりにsess
オブジェクトを使用する必要があることに注意してください。 ただし、オブジェクト自体は同じインターフェイスを提供します。
JSONAPIのテスト
バージョン1.0の新機能。
FlaskはJSONを強力にサポートしており、JSONAPIを構築するための一般的な選択肢です。 JSONデータを使用してリクエストを作成し、応答でJSONデータを調べると非常に便利です。
テストクライアントメソッドでjson
引数を渡すと、リクエストデータがJSONシリアル化されたオブジェクトに設定され、コンテンツタイプがapplication/json
に設定されます。 get_json
を使用して、リクエストまたはレスポンスからJSONデータを取得できます。
CLIコマンドのテスト
Clickには、CLIコマンドをテストするためのユーティリティが付属しています。 CliRunner
はコマンドを分離して実行し、Result
オブジェクトに出力をキャプチャします。
Flaskはtest_cli_runner()
を提供して、FlaskアプリをCLIに自動的に渡すFlaskCliRunner
を作成します。 invoke()
メソッドを使用して、コマンドラインから呼び出すのと同じ方法でコマンドを呼び出します。
上記の例では、コマンドを名前で呼び出すと、コマンドがアプリに正しく登録されていることが確認されるので便利です。
コマンドを実行せずに、コマンドがパラメーターを解析する方法をテストする場合は、make_context()
メソッドを使用します。 これは、複雑な検証ルールとカスタムタイプをテストする場合に役立ちます。