flaskでWebアプリ開発、テストを記述する4、認証機能の続き

1_プログラミング

flaskチュートリアルを前回の続きからやっていきます。今回は、認証機能のテスト用プログラムの続きと、ブログ機能の検証に入っていきます。

チュートリアル次のページとなります。

こんな人の役に立つかも

・PythonでWebアプリケーションを作成したい人

・flaskのチュートリアルを行なっている人

・flaskのチュートリアルでブログアプリflaskrを作成している人

スポンサーリンク

ログイン・ログアウト機能のテスト

前回は、auth.pyのregisterの機能をテストするためのプログラムを作成しました。ユーザーの認証機能は他にloginとlogoutがありますので、それらのテストを行うプログラムの作成となります。まずは、今回のプログラムがどのようなテストを行うかをまとめてみました。

検証するべき項目

今回テストを行う「ログイン処理」と「ログアウト処理」では次のようなテスト項目が必要になります。

ログイン時

・GETメソッドでログインフォームが正常に返されるか?

・POSTメソッドでログインを行って、localhostにリダイレクトされるか?

・セッションの中身の「user_id」が「1」となるか?

・アプリケーションコンテキストのg.userの内容に「test」が書き込まれているか?

・ログイン時に登録されていないユーザー名を入れると「Incorrext username」が返ってくるか?

・ログイン時に間違ったパスワードを入れると「Incorrect password」が返ってくるか?

ログアウト時

・ログアウト処理を行い、セッションの中身から「user_id」が取り除かれているか?

ソフトのバグを100%取り除くのは涙ぐましい努力が必要ですね・・・

テスト用プログラミング

前回のregisterと同様、「test_auth.py」に引き続き記載していきます。

ログイン機能の検証

まずは、ログイン機能からです。

#①関数test_loginは引数にfixture「client」と「auth」を取ります。
def test_login(client, auth):
    assert client.get('/auth/login').status_code == 200
    #「auth」fixtureによるPOSTメソッドでのログイン処理
    response = auth.login()
    assert response.headers['Location'] == 'http://localhost/'

    with client:
        client.get('/')
        assert session['user_id'] == 1
        assert g.user['username'] == 'test'


#②ログインフォームに入力するテスト関数test_login_validate_inputです。
@pytest.mark.parametrize(('username', 'password', 'message'), (
    ('a', 'test', b'Incorrect username.'),
    ('test', 'a', b'Incorrect password.'),
))
def test_login_validate_input(auth, username, password, message):
    response = auth.login(username, password)
    assert message in response.data

テストプログラムの構成は、前回のregisterと非常に類似しています。①の「test_login」関数を呼び出すことでログイン時の処理を行っています。ここでは、「conftest.py」に記載した「auth」fixtureが活躍していることがわかります。「auth」fixtureはログイン時ユーザーネーム「test」とパスワード「test」でログインするように作成しました。この関数は、②の「test_login_validate_input」で利用されます。

また、with clientブロックを利用しています。

with client:

このブロックを利用することで、コンテキスト変数にアクセスできるとのことです。getで「/」にアクセスしたときの「session」と「g」というコンテキスト変数の中身にアクセスしています。

②では、pytestのparametrizeデコレータを利用しています。「@pytest.mark.parametrize」でプログラムのように2パターンの引数を「test_login_validate_input」に与えることができるようになっています。「test_login」関数にパラメータ(フォームの入力値)を与えることで返ってくるメッセージが正しいかどうかをチェックしています。

ログアウト機能の検証

続けてログアウト処理も「test_auth.py」い記載していきます。

def test_logout(client, auth):
    auth.login()

    #コンテキスト変数「session」にアクセスするためwithします。
    with client:
        auth.logout()
        assert 'user_id' not in session

ログアウト処理に関してはシンプルで、ログアウトを行うとセッションの「user_id」が取り除かれます。そのため、ログアウト処理を行った後に「session」に「user_id」という項目が存在しないことを確認します。

この時も、コンテキスト変数「session」にアクセスしますので、「with client:」構文が必要になってきます。

flaskのテストプログラムの所感

チュートリアルでは、主にテスト用プログラムの実装方法に目が行きがちですが、テストで一番大切なことは、自分が作成しているアプリの想定する動作をどこまで細かく知っているか?という点な気がしてきました。

チュートリアルでは、ブログアプリを例にして作成していますが、実際に自分が作りたいオリジナルのアプリとなった場合、検証すべきテスト項目もオリジナルのものになってきます。

そうなったとき、特にアプリケーションコンテキストの「g」にこの値を入れていればOK、とか、セッションの中身にこの値が入っていればOKなど、そういった内部的なデータの流れもテストに入れられるようになっていけたらいいのかなと感じています。

タイトルとURLをコピーしました