Flaskで単体テストを実装する方法を解説
2024年7月11日
こんにちは!
FlaskはPythonで作られたWebフレームワークです。
Flaskを使ってWebアプリケーションを構築する際、コードの品質を保ち、バグを防ぐためには単体テストが重要です。
本記事では、Flaskアプリケーションにおける単体テストの実装方法について詳しく解説します。
単体テストとは?
そもそも単体テストとは何なのでしょうか?
単体テスト(Unit Test)は、ソフトウェア開発において個々のモジュールや関数が正しく動作するかを確認するためのテストです。これにより、特定の部分が期待通りに動作することを保証できます。
Flaskアプリケーションにおいては、ビュー関数やデータベースの操作、その他のロジックを含む各コンポーネントのテストが対象となります。
単体テストの準備
まずは、単体テストの実装の前に、FlaskのWebアプリを準備します。単体テストを試すためのものなので、簡単なWebページを返すものを作成します。
以下のコマンドを実行して、Flaskをインストールします。
pip install flask
その後、app.pyに以下のように設定します。
from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/hello', methods=['GET'])
def hello():
return jsonify({'message': 'Hello, World!'})
if __name__ == '__main__':
app.run(debug=True)
このアプリケーションは、/helloエンドポイントにGETリクエストが送られると、”Hello, World!” というメッセージをJSON形式で返します。
Flaskで単体テストを実装する
pytestとFlask-Testingのインストール
Flaskアプリケーションの単体テストを行うためには、ライブラリをインストールする必要があります。
一般的に使用されるのはpytestとFlask-Testingです。
以下のコマンドを実行してインストールしましょう。
pip install pytest Flask-Testing
テストコードの記述
テストコードは、testsディレクトリ内にtest_app.pyという名前で作成します。
ファイルの中身を以下のように記述します。
import unittest
from flask_testing import TestCase
from app import app
class MyTest(TestCase):
def create_app(self):
app.config['TESTING'] = True
return app
def test_hello(self):
response = self.client.get('/hello')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, {'message': 'Hello, World!'})
if __name__ == '__main__':
unittest.main()
現在のディレクトリ構造は、以下のようになっています。
flask_project/
│
├── app.py # ここにFlaskアプリケーション本体のコード
├── requirements.txt # 必要なライブラリ
├── tests/
│ └── test_app.py # テストスクリプト
└── ...
単体テストの実行
単体テストを実行するには、以下のようなコマンドを実行します。
python -m unittest discover -s tests
このコマンドは、testsディレクトリ内のすべてのテストスクリプトを自動的に検出し、実行します。
テストを実行すると、OKが返ってきます。
データベースのテスト
ここまで、Webページの出力がただしいかどうかの簡単なテストを実行しました。
単体テストでは、その他の項目もテストすることができます。
そのうちの1つがデータベースのテストです。
テスト用のアプリを作成
まず、データベースを使うためにパッケージをインストールします。
pip install Flask-SQLAlchemy
app.pyに以下の内容を追加します。
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
@app.route('/user', methods=['POST'])
def add_user():
username = request.json['username']
user = User(username=username)
db.session.add(user)
db.session.commit()
return jsonify({'id': user.id, 'username': user.username}), 201
if __name__ == '__main__':
app.run(debug=True)
このアプリケーションでは、ユーザー情報を保存するためのUserモデルと、新しいユーザーを追加するためのエンドポイント/userを定義しています。
DBの設定については、こちらの記事で詳しく解説しています。
【関連】Flask-SQLAlchemyとは?FlaskでDBを使おう
データベースのテストコード
次にテストコードを修正します。test/test_app.pyを以下のように修正しましょう。
import unittest
from flask_testing import TestCase
from app import app, db, User
class UserTest(TestCase):
#テスト用のFlaskアプリケーションを設定
def create_app(self):
app.config['TESTING'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
return app
#各テストケースの前に呼び出され、データベースを作成します
def setUp(self):
db.create_all()
#各テストケースの後に呼び出され、データベースセッションをクリアし、データベースを削除します
def tearDown(self):
db.session.remove()
db.drop_all()
#テストの実行をします
def test_add_user(self):
response = self.client.post('/user', json={'username': 'testuser'})
self.assertEqual(response.status_code, 201)
self.assertIn('id', response.json)
self.assertEqual(response.json['username'], 'testuser')
if __name__ == '__main__':
unittest.main()
test_add_users()関数で、テストの記述をしています。
各処理は、以下のような動きをしています。
1./user エンドポイントに対してPOSTリクエストを送信し、ユーザー名としてtestuserを送信します。
2.レスポンスのステータスコードが201(Created)であることを確認します。
3.レスポンスJSONにidキーが含まれていることを確認します。
4.レスポンスJSONのusernameフィールドがtestuserであることを確認します。これはリクエストで送信したユーザー名が正しく保存されていることを確認するためです。
単体テストの実行
最後に単体テストの実行をしてみます。
python -m unittest discover -s tests
以下のようにOKになれば成功です。
このように単体テストを行います。
単体テストの実装が完了したら、カバレッジの測定も行いましょう。カバレッジとは、テストがどの程度網羅的に行われているかを測る指標です。詳しくは、こちらの記事で解説しています。
【関連記事】Flaskでカバレッジ測定をする方法解説
まとめ
今回の記事では、Flaskの単体テストについて解説しました。
単体テストは、Webアプリの品質を高めるために大切なことです。もちろん単体テストの処理を記述するのは面倒ですが、後々のバグ修正の手間を考えると、、工数は少なくすみます。
また、CIツールと組み合わせることで、リリース前に自動でテストを実行することも可能です。このように、テストを有効活用して、システム開発の品質を高めていきましょう。
この記事が、あなたのWeb開発のお役になれば幸いです。
ここまでお読みいただきありがとうございました。
Pythonの基礎から応用まで学べる
Python WebAcademy
Python WebAcademyでは、Pythonの基礎からアーキテクチャなどの応用的な内容まで幅広く学べます。また、ブラウザ上で直接Pythonコードを試すことができ、実践的なスキルを身につけることが可能です。
無料で試すインフラの学習はInfraAcademy
おすすめの記事