5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

pytestを使用したFlask APIテスト メモ

Posted at
  • python用テストフレームワークpytestpytest-cov(カバレッジ計測用)を用いたFlask製APIのテスト方法についてメモする。

事前準備

  • pytestインストール

    pip install pytest
    
  • pytest-covインストール

    pip install pytest-cov
    

実装

ディレクトリ構成

Project
├─ sampleapi
│  ├─app.py
│  │
│  │
│  └─api
│    │  __init__.py
│    │
│    └─ views
│        └─sample.py
└─ test
    ├─  unit_test.py
    └─  __init__.py

  • sampleapiディレクトリ:テスト対象APIのコードを格納。
  • testディレクトリ:テストコードを格納。

テスト対象API

  • sampleapi/app.py

    from api import app
    
    if __name__ == '__main__':
        app.run()
    
  • sampleapi/api/init.py

    from flask import Flask
    from .views.sample import sample_router
    
    
    def create_app():
    
        app = Flask(__name__)
    
        app.register_blueprint(sample_router, url_prefix='/api')
    
        return app
    
    
    app = create_app()
    
  • sampleapi/views/sample.py

    from flask import Flask, Blueprint, request
    import json
    
    # Routing Settings
    sample_router = Blueprint('sample_router', __name__)
    
    app = Flask(__name__)
    
    
    @sample_router.route("/sample",  methods=['GET'])
    def get():
    
        res_body = {}
        query = request.args.get('q')
        if query is not None:
            res_body = {
                "id": "XXXYYYZZZ",
                "name": "Sample",
                "query": query
            }
        else:
            res_body = {
                "id": "XXXYYYZZZ",
                "name": "Sample",
                "query": "None"
            }
        return json.loads(json.dumps(res_body))
    

テストコード

  • test/__init__.py:空ファイル

  • test/unit_test.py:テストコード

    import pytest
    # テスト対象APIコードのappをインポート
    from sampleapi.api import app
    
    def test_flask_N001():
        # テスト用コンフィグをtrueに設定
        app.config['TESTING'] = True
        # テスト対象API呼び出し用テストクライアント生成
        client = app.test_client()
    
        # テスト対象API実行
        result = client.get('/api/sample')
        body = result.get_json()
    
        # レスポンス結果と期待値の比較
        assert 'XXXYYYZZZ' == body['id']
        assert 'Sample' == body['name']
        assert 'None' == body['query']
    
    
    def test_flask_N002():
        # テスト用コンフィグをtrueに設定
        app.config['TESTING'] = True
        # テスト対象API呼び出し用テストクライアント生成
        client = app.test_client()
    
        # テスト対象API実行(クエリパラメータ指定あり)
        result = client.get('/api/sample?q=Test')
        body = result.get_json()
    
        # レスポンス結果と期待値の比較
        assert 'XXXYYYZZZ' == body['id']
        assert 'Sample' == body['name']
        # クエリパラメータに指定した値が設定されていることを確認
        assert 'Test' == body['query']
    
    

動作確認

  • テスト実行

    pytest -v unit_test.py
    ======================================= test session starts ========================================
    platform win32 -- Python 3.8.3, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- c:\python38\python.exe     
    cachedir: .pytest_cache
    rootdir: C:\Users\user\Desktop\FlaskApi\test
    plugins: cov-2.11.1
    collected 2 items
    
    unit_test.py::test_flask_N001 PASSED                                                          [ 50%]
    unit_test.py::test_flask_N002 PASSED                                                          [100%] 
    
    ======================================== 2 passed in 0.91s ========================================
    
  • カバレッジ計測

    • C0

      pytest --cov -v unit_test.py
      ~~ 省略 ~~
      
    • C1

      pytest --cov --cov-branch -v unit_test.py
      ~~ 省略 ~~
      

参考情報

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?