サーチ…


Hello Worldアプリのテスト

前書き

この最小限の例では、 pytestを使って、Hello Worldアプリケーションが "Hello、World!"を返すかpytestをテストします。 HTTP OKステータスコード200で、URL / URLのGETリクエストでヒットすると、

まずpytestにインストールしましょう

pip install pytest

ちょうど参考のために、この私たちのこんにちは世界のアプリ:

# hello.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

テストの定義

サイド当社に沿っhello.py 、我々はと呼ばれるテストモジュール定義test_hello.pyによって発見されようとしているpy.test

# test_hello.py
from hello import app

def test_hello():
    response = app.test_client().get('/')

    assert response.status_code == 200
    assert response.data == b'Hello, World!'

この時点で、 treeコマンドで得られたプロジェクトの構造は次のようになります。

.
├── hello.py
└── test_hello.py

テストの実行

今度は、このテストをpy.testコマンドで実行して、 test_hello.pyとその中のテスト関数を自動的に発見します

$ py.test

いくつかの出力と1つのテストが合格したという表示が表示されます。

=== test session starts ===
collected 1 items 
test_hello.py .
=== 1 passed in 0.13 seconds ===

Flaskで実装されたJSON APIのテスト

この例では、pytestを使ってFlaskアプリケーションをテストする方法を知っていることを前提としています

以下は、整数値ab例えば{"a": 1, "b": 2}を持つJSON入力を取得し、それらを合計してJSONレスポンスでsum a + bを返すAPIです(例: {"sum": 3}

# hello_add.py
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/add', methods=['POST'])
def add():
    data = request.get_json()
    return jsonify({'sum': data['a'] + data['b']})

pytestこのAPIをpytest

pytestテストできます

# test_hello_add.py
from hello_add import app
from flask import json

def test_add():        
    response = app.test_client().post(
        '/add',
        data=json.dumps({'a': 1, 'b': 2}),
        content_type='application/json',
    )

    data = json.loads(response.get_data(as_text=True))

    assert response.status_code == 200
    assert data['sum'] == 3

py.testコマンドでテストを実行します。

Flask-Testingを使用したテストでのセッション変数へのアクセスと操作

ほとんどのWebアプリケーションは、セッションオブジェクトを使用していくつかの重要な情報を保存します。この例では、Flask-Testingを使用してそのようなアプリケーションをテストする方法を示します。完全な実例もgithubで利用できます。

だから最初にあなたのvirtualenvでFlask-Testingをインストールしてください

pip install flask_testing

セッションオブジェクトを使用できるようにするには、秘密鍵を設定する必要があります

app.secret_key = 'my-seCret_KEy'

このようなセッション変数にデータを格納する必要があるアプリケーション関数があるとしましょう

@app.route('/getSessionVar', methods=['GET', 'POST'])
def getSessionVariable():
  if 'GET' == request.method:
    session['sessionVar'] = 'hello'
  elif 'POST' == request.method:
    session['sessionVar'] = 'hi'
  else:
    session['sessionVar'] = 'error'

  return 'ok'

この関数をテストするには、flask_testingをインポートして、テストクラスがflask_testing.TestCaseを継承できるようにします。必要なすべてのライブラリもインポートする

import flask
import unittest
import flask_testing
from myapp.run import app
    
class TestMyApp(flask_testing.TestCase):

テストを開始する前に非常に重要なのは、 create_app関数を実装することです。それ以外の場合は例外があります。

  def create_app(self):
    return app

アプリケーションをテストするには、いくつかの可能性があります。あなたの関数が特定の値をセッション変数に設定していることを保証したいのであれば、コンテキストを保持してflask.sessionにアクセスすることができます

def testSession1(self):
    with app.test_client() as lTestClient:
      lResp= lTestClient.get('/getSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['sessionVar'], 'hello')

もう一つの便利なトリックは、次のテスト関数のようなGETメソッドとPOSTメソッドを区別することです

def testSession2(self):
    with app.test_client() as lTestClient:
      lResp= lTestClient.post('/getSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['sessionVar'], 'hi')

あなたの関数がセッション変数を設定することを期待し、このような特定の値に対して異なった反応をすることを想像してみましょう

@app.route('/changeSessionVar')
def changeSessionVariable():
  if session['existingSessionVar'] != 'hello':
    raise Exception('unexpected session value of existingSessionVar!')

  session['existingSessionVar'] = 'hello world'
  return 'ok'

この機能をテストするには、いわゆるセッショントランザクションを使用し、テストクライアントのコンテキストでセッションを開く必要があります。この機能はFlask 0.8以降で利用可能です

def testSession3(self):
    with app.test_client() as lTestClient:
      #keep the session
      with lTestClient.session_transaction() as lSess:
        lSess['existingSessionVar'] = 'hello'

      #here the session is stored
      lResp = lTestClient.get('/changeSessionVar')
      self.assertEqual(lResp.status_code, 200)
      self.assertEqual(flask.session['existingSessionVar'], 'hello world')

テストの実行はunittestの場合と同じです

if __name__ == "__main__":
    unittest.main()

そして、コマンドラインで

python tests/test_myapp.py

テストを実行するもう一つの良い方法は、unittest Discoveryを次のように使用することです。

python -m unittest discover -s tests


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow