Python テストの新たな可能性:FastAPI アプリケーションと SQLAlchemy テストフィクスチャでテストをもっと楽しく
SQLAlchemy テストフィクスチャを用いた FastAPI アプリケーションのテスト方法
FastAPI は Python で高性能な API を構築するためのフレームワークです。 SQLAlchemy は Python でデータベースとやり取りするための ORM ライブラリです。 テストフィクスチャは、テストケースで使用する事前定義されたデータセットです。
本記事では、SQLAlchemy テストフィクスチャを使用して FastAPI アプリケーションをテストする方法を説明します。
要件
このチュートリアルを完了するには、以下の要件を満たす必要があります。
- Python 3.7 以降
- pip
- FastAPI
- SQLAlchemy
- pytest
手順
-
プロジェクトのセットアップ
まず、新しい FastAPI プロジェクトを作成します。 以下のコマンドを実行して、仮想環境を作成し、必要なパッケージをインストールします。
python3 -m venv venv source venv/bin/activate pip install fastapi sqlalchemy pytest
-
モデルとデータベースの定義
次に、モデルとデータベースを定義します。 以下の例では、
User
モデルとusers
テーブルを定義します。from sqlalchemy import Column, Integer, String from sqlalchemy.orm import declarative_base from sqlalchemy import create_engine Base = declarative_base() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True) name = Column(String(255)) email = Column(String(255)) engine = create_engine("sqlite:///test.db") Base.metadata.create_all(engine)
-
テストフィクスチャの作成
次に、テストフィクスチャを作成します。 テストフィクスチャは、テストケースで使用する事前定義されたデータセットです。 以下の例では、
User
モデルのインスタンスを 2 つ作成するテストフィクスチャを作成します。from sqlalchemy.orm import sessionmaker SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) @pytest.fixture def users(): db = SessionLocal() user1 = User(name="John Doe", email="[email protected]") user2 = User(name="Jane Doe", email="[email protected]") db.add(user1) db.add(user2) db.commit() yield user1, user2 db.rollback() db.close()
-
テストケースの作成
最後に、テストケースを作成します。 テストケースは、アプリケーションの動作を検証するコードです。 以下の例では、
users
エンドポイントが正しいユーザーを返すことを検証するテストケースを作成します。from fastapi.testclient import TestClient from main import app def test_get_users(users): client = TestClient(app) response = client.get("/users/") assert response.status_code == 200 assert response.json() == [{"id": 1, "name": "John Doe", "email": "[email protected]"}, {"id": 2, "name": "Jane Doe", "email": "[email protected]"}]
このテストケースを実行するには、以下のコマンドを実行します。
pytest
このテストケースは成功するはずです。
# ファイル: main.py
from fastapi import FastAPI
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
engine = create_engine("sqlite:///test.db")
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String(255))
email = Column(String(255))
Base.metadata.create_all(engine)
app = FastAPI()
@app.get("/users/")
def get_users(db: Session = Depends(SessionLocal)):
users = db.query(User).all()
return users
# ファイル: tests.py
from fastapi.testclient import TestClient
from main import app
import pytest
@pytest.fixture
def users():
db = SessionLocal()
user1 = User(name="John Doe", email="[email protected]")
user2 = User(name="Jane Doe", email="[email protected]")
db.add(user1)
db.add(user2)
db.commit()
yield user1, user2
db.rollback()
db.close()
def test_get_users(users):
client = TestClient(app)
response = client.get("/users/")
assert response.status_code == 200
assert response.json() == [{"id": 1, "name": "John Doe", "email": "[email protected]"}, {"id": 2, "name": "Jane Doe", "email": "[email protected]"}]
User
という名前のモデルを持つusers
テーブルを持つ SQLite データベース/users/
エンドポイントは、データベース内のすべてのユーザーを返しますusers
テストフィクスチャは、2 人のユーザーを作成し、テストケースで使用するセッションを提供しますtest_get_users
テストケースは、get_users
エンドポイントが正しいユーザーを返すことを検証します
以下の点に注意してください。
- このコードは単純な例であり、本番環境で使用するためには十分ではありません。
- テストケースは、アプリケーションのすべての機能を網羅する必要があります。
- テストフィクスチャは、テストケースで使用するデータを簡単に定義して管理するために使用できます。
setup_class
とteardown_class
デコレータconftest.py
ファイル- サードパーティ製ライブラリ
setup_class
と teardown_class
デコレータを使用して、テストクラス全体で実行される前処理と後処理を定義できます。 以下の例では、setup_class
デコレータを使用してテスト用にデータベースを作成し、teardown_class
デコレータを使用してデータベースを削除します。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
class TestUsers:
engine = create_engine("sqlite:///test.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@classmethod
def setup_class(cls):
Base.metadata.create_all(cls.engine)
@classmethod
def teardown_class(cls):
cls.engine.drop_all()
def test_get_users():
db = SessionLocal()
# ...
conftest.py
ファイルを使用して、プロジェクト全体のテストフィクスチャを定義できます。 以下の例では、conftest.py
ファイルを使用して、テスト用にデータベースを作成し、セッションを提供します。
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine("sqlite:///test.db")
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@pytest.fixture
def db():
yield SessionLocal()
各テストケースで、db
フィクスチャを使用してセッションを取得できます。
def test_get_users(db):
# ...
テストフィクスチャを管理するためのサードパーティ製ライブラリを使用することもできます。 人気のあるライブラリには、以下のものがあります。
これらのライブラリは、より複雑なテストフィクスチャを定義および管理するのに役立ちます。
sqlalchemy fastapi test-fixture