概要
flasgger で作成したアプリを unittest でテストしてみました
アプリは Marshmallow Schemas で作成しています
Mock との連携方法も紹介します
環境
- macOS X 10.13.6
- Python 3.6.5
- flasgger 0.9.0
テスト対象のアプリ
- vim test_app.py
# coding: utf-8
from flask import Flask, jsonify
from flasgger import Schema, Swagger, SwaggerView, fields
class CategorySchema(Schema):
id = fields.Int()
name = fields.Str(required=True)
class PetSchema(Schema):
category = fields.Nested(CategorySchema, many=True)
name = fields.Str()
class RandomView(SwaggerView):
summary = 'A cute furry animal endpoint.'
description = 'Get a random pet'
parameters = [
{
'name': 'id',
'in': 'path',
'required': True,
'type': 'integer'
}
]
responses = {
200: {
'description': 'A pet to be returned',
'schema': PetSchema
}
}
def get(self, id):
pet = self.external_api(id)
return jsonify(PetSchema().dump(pet).data)
def external_api(self, id):
return {'category': [{'id': id, 'name': 'rodent'}], 'name': 'Mickey'}
app = Flask(__name__)
app.add_url_rule(
'/random/<id>',
view_func=RandomView.as_view('random'),
methods=['GET']
)
if __name__ == '__main__':
app.run(debug=True)
こんな感じのアプリです
/random/1
に GET すると適当な JSON が返ってきます
普通に unittest でテストする
- vim test1.py
import unittest
import json
import test_app
class TestApp(unittest.TestCase):
def setUp(self):
self.app = test_app.app.test_client()
def testGet(self):
res = self.app.get('/random/1')
self.assertEqual(
{'category':[{'id':1,'name':'rodent'}],'name':'Mickey'},
res.get_json()
)
if __name__ == '__main__':
unittest.main()
pipenv run python3 -m unittest test1.py
ポイントは test_app.app.test_client()
で Flask アプリ用のクライアントを作成している点です
このクライアントの get や post といったメソッドをコールすることでアプリにリクエストすることができます
Mock を使ってテストする
次に unittest.MagicMock を使ってテストします
external_api
というメソッドを Mock してみたいと思います
- vim test2.py
import unittest
from unittest.mock import patch, MagicMock
import json
import test10
class TestApp(unittest.TestCase):
def setUp(self):
self.app = test10.app.test_client()
@patch('test10.RandomView.external_api')
def testMockGet(self, mock):
mock.return_value = {'category':[{'id':100,'name':'rodent'}],'name':'Mickey'}
print(mock)
res = self.app.get('/random/1')
self.assertEqual(
{'category':[{'id':100,'name':'rodent'}],'name':'Mickey'},
res.get_json()
)
if __name__ == '__main__':
unittest.main()
ポイントは @patch('test10.RandomView.external_api')
です
関数まで patch 当てます
すると引数の mock に MagicMock クラスのオブジェクトが返ってきます
更に mock は patch のおかげで関数にもなっているのであとは return_value
で返り値を設定するだけです
今回は id:100
を Mock が返すように設定しています
pipenv run python3 -m unittest test2.py
最後に
flasgger で作成したアプリに対して unittest を適用してみました
Mock も使ってみましたが SwaggerView で定義した内容を Mock することで意図するテストを書くことができました
公式にテストの方法は書いてませんでしたが、Flask の test_client
と標準の unittest を使っているので特に追加のモジュールなしでテストできるのは嬉しい点だと思います
0 件のコメント:
コメントを投稿