OpenAPIまたはGraphQLスキーマがあるなら、SchemathesisでAPIに対する大量のテストケースを自動生成できます。アサーションを1行も書かずに、仕様から入力を生成し、実行中のAPIへ送信し、レスポンスが契約に違反していないかを検出します。この記事では、Schemathesisの基本、インストール、実行方法、プロパティベーステストの考え方、そして契約テストやApidogとの使い分けを実装寄りに整理します。
Schemathesisとは?
Schemathesisは、OpenAPIまたはGraphQLスキーマからAPIテストを自動生成するオープンソースのPythonツールです。スキーマに定義された型、フォーマット、制約をもとにリクエストを生成し、APIが仕様どおりに振る舞うかを検証します。
内部では、PythonのプロパティベーステストライブラリであるHypothesisを利用しています。ライセンスはMITです。
Schemathesisの前提はシンプルです。
- OpenAPI / GraphQLスキーマは「正しいAPI契約」を表す
- 実装はその契約に従うべき
- 仕様上有効な入力で500エラーになるならバグ
- レスポンスが定義済みスキーマに合わないなら契約違反
- 仕様にないステータスコードやContent-Typeを返すなら不整合
CLIでは次のように実行します。
st run http://127.0.0.1:8000/openapi.json
stはschemathesisコマンドの短縮エイリアスです。
schemathesis run http://127.0.0.1:8000/openapi.json
どちらも同じ動作をします。
プロパティベーステストとは?
一般的なAPIテストは「例ベース」です。
たとえば、次のように固定の入力と期待値を用意します。
GET /users/123
期待する結果は次のようなものです。
{
"id": 123,
"name": "Alice"
}
この方式は重要ですが、テストを書いたケースしか検証できません。
一方、プロパティベーステストでは「常に満たすべき性質」を定義し、ツールが多数の入力を生成してその性質を壊そうとします。
Schemathesisの場合、主なプロパティは次のようになります。
- 有効なリクエストでサーバーがクラッシュしない
- レスポンスボディがスキーマに一致する
- ステータスコードが仕様に定義されている
- Content-Typeが仕様に一致する
- 境界値や特殊な入力でも契約を破らない
たとえばOpenAPIに次のような制約があるとします。
components:
schemas:
Product:
type: object
required:
- price
properties:
price:
type: integer
minimum: 1
Schemathesisはpriceに対して、最小値、境界値、大きな値、想定外の組み合わせなどを生成し、APIが仕様どおり処理できるかを確認します。
テストが失敗すると、Hypothesisが失敗入力をできるだけ小さく縮小します。これにより、巨大なランダムペイロードではなく、再現しやすい最小ケースを得られます。
これはモンキーテストとは異なります。モンキーテストはランダム入力でクラッシュを探しますが、Schemathesisはスキーマを使って構造化された入力を生成し、仕様に基づいて正否を判断します。
Schemathesisのインストール
SchemathesisはPythonパッケージです。Python 3とpipが必要です。
pip install schemathesis
インストール後、バージョンを確認します。
st --version
または次のように実行します。
schemathesis --version
uvを使っている場合は、グローバルインストールせずに実行できます。
uvx schemathesis run http://127.0.0.1:8000/openapi.json
OpenAPIスキーマに対して実行する
スキーマがURLで公開されている場合は、そのURLを渡します。
st run http://127.0.0.1:8000/openapi.json
OpenAPIファイルがローカルにある場合は、スキーマファイルとAPIのベースURLを指定します。
st run ./openapi.yaml --url http://127.0.0.1:8000
JSON形式でも同様です。
st run ./openapi.json --url http://127.0.0.1:8000
Schemathesisは仕様内の各operationを読み取り、リクエストを生成して実行します。失敗時には、再現に使えるリクエスト情報が出力されます。
認証付きAPIをテストする
Bearerトークンが必要なAPIでは、--headerを使います。
st run http://127.0.0.1:8000/openapi.json \
--header 'Authorization: Bearer your-token'
複数ヘッダーも指定できます。
st run ./openapi.yaml \
--url http://127.0.0.1:8000 \
--header 'Authorization: Bearer your-token' \
--header 'X-Request-Source: schemathesis'
Cookie認証や独自ヘッダーを使う場合も、同じようにヘッダーとして渡します。
st run ./openapi.yaml \
--url http://127.0.0.1:8000 \
--header 'Cookie: session=your-session-id'
利用できるオプションはバージョンで変わる可能性があるため、実行環境で必ず確認してください。
st run --help
Schemathesisが検出する問題
Schemathesisは、仕様と実装のズレを検出します。
| 問題 | 例 |
|---|---|
| サーバーエラー | 有効なリクエストで500エラーになる |
| スキーマ違反 | レスポンスボディがOpenAPIで定義したスキーマに一致しない |
| ステータスコードの不一致 | 仕様にないステータスコードを返す |
| Content-Typeのずれ |
application/jsonと定義しているのに別のContent-Typeを返す |
| ステートフルなバグ | 作成、取得、更新、削除などの流れの中で不整合が起きる |
たとえば、仕様では200と404だけを定義しているのに、実装が500を返す場合は失敗として報告されます。
paths:
/users/{id}:
get:
responses:
"200":
description: OK
"404":
description: Not Found
このAPIがある入力で500 Internal Server Errorを返すなら、Schemathesisは契約違反として扱います。
ステートフルテスト
Schemathesisは、単一リクエストだけでなく、複数ステップのAPIフローも検証できます。
たとえば次のような流れです。
- リソースを作成する
- 作成したリソースを取得する
- リソースを更新する
- 更新後の内容を確認する
- リソースを削除する
- 削除後に取得できないことを確認する
単体のエンドポイントでは問題がなくても、順序付きの操作でのみ発生するバグがあります。
例:
- 作成直後のGETで古い状態が返る
- 更新後に一部フィールドだけ反映されない
- 削除後も一覧に残る
- 作成レスポンスのIDが後続APIで使えない
こうした問題は、単発のAPIテストでは見逃されやすいです。Schemathesisのステートフルテストは、仕様内のリンク情報などをもとに操作を連結し、状態遷移を検証します。
フックで挙動をカスタマイズする
SchemathesisはPythonのフックで拡張できます。
フックを使うと、次のような調整ができます。
- 生成データをカスタマイズする
- 特定のエンドポイントだけを対象にする
- 独自のチェックを追加する
- 認証や事前条件を補う
- 仕様だけでは表現しにくい制約を反映する
たとえば、すべてのケースに追加ヘッダーを付けたい場合や、特定の操作を除外したい場合に使います。
実際のフックAPIはSchemathesisのバージョンにより変わる可能性があるため、導入時は公式ドキュメントとst run --helpを確認してください。
CIで実行する
SchemathesisはCLIで動くため、CIに組み込みやすいです。
GitHub Actionsでは、たとえば次のように実行できます。
name: API fuzzing
on:
pull_request:
push:
branches:
- main
jobs:
schemathesis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Schemathesis
run: pip install schemathesis
- name: Run API server
run: |
# 例: ここでテスト対象APIを起動する
# docker compose up -d
echo "Start your API here"
- name: Run Schemathesis
run: |
st run ./openapi.yaml --url http://127.0.0.1:8000
認証が必要な場合は、CIのSecretsからトークンを渡します。
- name: Run Schemathesis
run: |
st run ./openapi.yaml \
--url http://127.0.0.1:8000 \
--header "Authorization: Bearer ${{ secrets.API_TOKEN }}"
CIでは、まず対象を絞って導入するのが現実的です。
おすすめの進め方は次のとおりです。
- ローカルで
st runを実行する - 失敗するエンドポイントを確認する
- 仕様の誤りと実装のバグを切り分ける
- 重要なAPIだけCIに追加する
- 安定したら対象範囲を広げる
Schemathesisを使うべきタイミング
Schemathesisが特に有効なのは、次のような状況です。
- OpenAPI仕様を管理している
- 仕様と実装のズレを自動検出したい
- 500エラーや未処理例外をCIで検出したい
- 境界値や異常系を手作業で書ききれない
- APIに状態を持つ複数ステップのワークフローがある
- Python、pip、pytestベースのツールに慣れている
一方で、次のような場合は注意が必要です。
- スキーマが古い
- スキーマが実装と一致していない
- レスポンス定義が曖昧
- エラー形式が仕様化されていない
- ビジネスロジックの正しさを検証したい
Schemathesisは、スキーマに書かれていることをもとにテストします。仕様が薄い場合、検出できる問題も限定されます。
また、Schemathesisは例ベースの機能テストを置き換えるものではありません。
たとえば、次のような検証は別途必要です。
- 割引計算が正しい
- 権限ごとの表示項目が正しい
- 注文ステータスの遷移が正しい
- 特定の入力に対して期待する業務結果を返す
Schemathesisは「未知の壊れ方」を探すためのレイヤーとして使い、既知の期待値は通常の機能テストで検証するのが実用的です。
SchemathesisとApidogの使い分け
ApidogとSchemathesisは役割が異なります。
Apidogは、APIの設計、デバッグ、テスト、モック、ドキュメント作成をまとめて扱うためのプラットフォームです。Schemathesisは、スキーマ駆動のプロパティベースファジングに特化したツールです。
重要なのは、Apidogはプロパティベースファジングを行うツールではないという点です。Apidogにはモンキーテストがありますが、これはSchemathesisのようなスキーマ駆動のプロパティベーステストとは異なります。
| ワークフロー | Schemathesis | Apidog |
|---|---|---|
| 仕様からのプロパティベースファジング | はい | いいえ |
| ビジュアルAPI設計 | いいえ | はい |
| OpenAPI仕様の編集 | いいえ | はい |
| 例ベースの機能テスト | 限定的 | はい |
| 仕様に対する契約テスト | 部分的 | はい |
| スキーマからのモックサーバー | いいえ | はい |
| CIでの実行 | はい、st run
|
はい、apidog run
|
| APIドキュメント生成 | いいえ | はい |
実用的には、次のように組み合わせます。
- ApidogでAPI仕様を設計・管理する
- Apidogで機能テストケースを作る
- Apidogでモックサーバーやドキュメントを生成する
-
apidog runでCI上の機能テストを実行する - 同じOpenAPI仕様に対してSchemathesisを実行する
- Schemathesisで境界値、クラッシュ、契約違反を検出する
この構成では、Apidogが「既知の期待値」を検証し、Schemathesisが「未知の壊れ方」を探します。
OpenAPI仕様から実行可能なテストスイートを作りたい場合は、ApidogでOpenAPI仕様からAPIテストコレクションを直接生成できます。Apidogをダウンロードして、仕様設計から機能テストまでの流れを試せます。
よくある質問
Schemathesisは無料ですか?
はい。SchemathesisはMITライセンスのオープンソースツールです。CLIは次のコマンドで無料でインストールして実行できます。
pip install schemathesis
ローカル環境やCIで使うコアツールは無料です。チーム向けのホスト型商用サービスもありますが、Schemathesis CLI自体はオープンソースです。
schemathesis runとst runの違いは何ですか?
違いはありません。
stはschemathesisの短縮エイリアスです。
schemathesis run ./openapi.yaml --url http://127.0.0.1:8000
次のコマンドと同じです。
st run ./openapi.yaml --url http://127.0.0.1:8000
好みの書き方を使って問題ありません。
Schemathesisは機能APIテストを置き換えますか?
いいえ。Schemathesisは機能テストの代替ではありません。
Schemathesisが得意なのは、次のような検証です。
- サーバーがクラッシュしない
- レスポンスがスキーマに一致する
- 仕様にないステータスコードを返さない
- 境界値や特殊入力でも契約を守る
一方、次のようなビジネスロジックは、例ベースの機能テストで検証する必要があります。
- 割引計算が正しい
- 注文金額が正しい
- 権限によって返すデータが変わる
- 特定条件で特定のステータスに遷移する
このようなテストは、Apidogで構築・実行できる例ベースの機能テストや契約テストで扱うのが適しています。
SchemathesisはGraphQLで使えますか?
はい。SchemathesisはOpenAPIとGraphQLの両方をサポートしています。
GraphQLでは、スキーマの型定義をもとにクエリを生成し、レスポンスを検証します。REST APIに対するOpenAPIベースの検証と同じように、仕様に基づいたテストを実行できます。
まとめ
Schemathesisは、OpenAPIまたはGraphQLスキーマから大量のAPIテストを生成し、実行中のAPIに対してプロパティベーステストを行うツールです。例ベースのテストでは見逃しやすい500エラー、境界値の不具合、スキーマ違反、契約のズレを検出できます。
ただし、SchemathesisはAPI設計、モック、ドキュメント生成、ビジネスロジック検証のためのツールではありません。
実践的には、次の構成が扱いやすいです。
- ApidogでAPI仕様を設計・管理する
- Apidogで機能テスト、モック、ドキュメントを作る
-
apidog runでCI上の既知ケースを検証する - Schemathesisで同じ仕様に対してファジングを実行する
- 未知のクラッシュや契約違反を検出する
APIライフサイクル全体を管理しながら、Schemathesisでエッジケースを探索する構成にすると、仕様、実装、テストのズレを継続的に見つけやすくなります。Apidogをダウンロードして設計と機能テストの基盤を整え、Schemathesisをファジングレイヤーとして追加してください。

Top comments (0)