Back to Blog

Flaskで単体テストを実装する方法を解説

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コードを試すことができ、実践的なスキルを身につけることが可能です。

無料で試す