OpenAPIファイルを保持していても、実行中のサービスが徐々に仕様から乖離していくことがあります。Specmaticは、その乖離をCIで検出し、仕様をスタブとしても実行するための契約テストツールです。この記事では、Specmaticの使いどころ、例ベースのテストとの違い、CLI/Dockerでの実行方法、そして ApidogのAPI契約テスト のようなプラットフォーム型アプローチとの違いを整理します。Specmaticが信頼できる情報源として読み込む代表的な仕様形式は OpenAPI Specification です。
Specmaticとは
Specmatic は、契約駆動開発のためのオープンソースツールです。API仕様を「ドキュメント」ではなく「実行可能な契約」として扱います。
OpenAPIファイルを渡すと、主に2つの用途で使えます。
- 実行中のAPIに対して契約テストを実行する
- OpenAPI仕様からスタブサーバーを起動する
つまり、同じ仕様ファイルを使って、プロバイダー側の検証とコンシューマー側の開発支援を行えます。
たとえば、プロバイダー側では次を検証できます。
- 定義されたパスが実装されているか
- 期待されるステータスコードを返すか
- レスポンスボディがスキーマに一致するか
- 不正なリクエストを仕様どおりに拒否するか
コンシューマー側では、実バックエンドが完成する前でも、契約に従ったスタブに対してフロントエンドや他サービスを実装できます。
SpecmaticはOpenAPI以外にも対応しています。バージョン2.0ではGraphQLとgRPCが追加され、イベント契約にはAsyncAPI、さらにWSDLやAvroのような形式もサポートしています。ただし、多くのチームではOpenAPIのYAMLまたはJSONファイルから導入するのが最も現実的です。
CLIまたはDockerイメージで実行できるため、CIにも組み込みやすい構成です。開発元は商用アドオンも提供していますが、コアとなる契約エンジンは無料でオープンソースです。
契約テストと例ベースのテストの違い
APIテストでよくあるのは、例ベースのテストです。
たとえば、次のようなテストを書きます。
curl http://localhost:8080/users/1
そして、レスポンスに対して以下を確認します。
- ステータスコードが
200である -
idが存在する -
nameが期待値に一致する
これは有効ですが、テストした例しか検証できません。エンドポイントが40個ある場合、必要なテストケースも増え、仕様変更時のメンテナンス負荷も大きくなります。
契約テストでは、個別の例ではなく、サービスが仕様全体に合致しているかを検証します。SpecmaticはOpenAPIスキーマを読み込み、そこからテストを生成します。
確認対象は、たとえば次のような項目です。
- レスポンスが宣言された型に一致しているか
- 必須フィールドが存在するか
- ステータスコードが仕様と一致しているか
- 不正なリクエストに対して適切に失敗するか
アサーションを1つずつ書くのではなく、OpenAPI仕様そのものをアサーションとして使うのがポイントです。
| 側面 | 例ベースのテスト | Specmaticによる契約テスト |
|---|---|---|
| 信頼できる情報源 | 手書きのテストケース | OpenAPI仕様そのもの |
| 維持するもの | 個々のリクエストとアサーション | 既存の仕様 |
| カバレッジ | 書いたケースのみ | 仕様が宣言する操作 |
| 乖離の検出 | 手動になりやすい | 仕様変更時に自動検出 |
| 典型的な失敗 | 特定の例が壊れた | サービスが契約に合致しなくなった |
契約テストには複数のスタイルがあります。
Pact のようなコンシューマー駆動契約テストでは、コンシューマーが期待をブローカーに公開し、プロバイダーがそれを検証します。
一方、Specmaticは契約駆動テストです。OpenAPIなどの仕様が、プロバイダーとコンシューマーの共有契約になります。Specmaticは、その契約に対してプロバイダーを検証し、同じ契約からコンシューマー向けのスタブを起動します。
Pactブローカーの代替ではなく、共有仕様を中心にした契約テストツールと考えると理解しやすいです。関連ツールの全体像を見たい場合は、API契約テストおよびモックツール の概要も参考になります。
Specmaticの実行方法
SpecmaticはCLIを直接インストールするか、Dockerイメージで実行できます。
CIに組み込む場合は、ローカル環境への依存を減らせるDockerが扱いやすいです。
契約テストを実行する
testコマンドでは、OpenAPI仕様と実行中のサービスURLを指定します。
# ネイティブCLI
specmatic test api.yaml --testBaseURL=http://localhost:8080
Dockerで実行する場合は、カレントディレクトリをコンテナにマウントします。
docker run -v "$(pwd):/usr/src/app" specmatic/specmatic \
test api.yaml --testBaseURL=http://host.docker.internal:8080
このコマンドにより、Specmaticは次を実行します。
-
api.yamlを読み込む - 仕様に定義された操作からリクエストを生成する
-
--testBaseURLにリクエストを送信する - レスポンスをOpenAPIスキーマに対して検証する
- 契約に合わない場合はテストを失敗させる
テストが失敗した場合、原因は大きく2つです。
- 実装が仕様に合っていない
- 仕様が実装の現状を反映していない
どちらが正しい契約なのかを判断し、実装または仕様を修正します。
仕様をスタブとして実行する
スタブサーバーを起動すると、SpecmaticはOpenAPI仕様に一致するレスポンスを返します。
specmatic stub api.yaml --port=9000
これにより、実バックエンドが未完成でも、コンシューマーは次のように開発できます。
curl http://localhost:9000/users/1
デフォルトでは、Specmaticはスキーマに準拠したレスポンスを生成します。
より現実的なデータを返したい場合は、仕様ファイルの隣に_examplesディレクトリを置き、具体的なリクエスト・レスポンス例を保存できます。リクエストが一致すると、スタブはその例を返します。
これにより、次のような開発が可能になります。
- フロントエンドがバックエンド完成前に画面実装を進める
- ダウンストリームサービスが依存先APIを待たずに開発を進める
- CIで外部サービス依存を減らす
スタブやモックサーバーの選定観点を比較したい場合は、契約テストおよびモックサーバー のまとめも参考になります。
既存サービスから仕様を生成する
Specmaticは、既存サービスの前段にプロキシとして配置し、実際のリクエストとレスポンスをキャプチャして、OpenAPIドキュメントとサンプルファイルを生成することもできます。
これは、次のようなケースで役立ちます。
- 既存APIは動いているがOpenAPI仕様がない
- 仕様ファーストに移行したい
- 現在のトラフィックからサンプルを作りたい
契約としての仕様とスタブモデル
Specmaticの重要な点は、1つの仕様ファイルをテストとスタブの両方で使うことです。
プロバイダー側の流れは次のようになります。
specmatic test api.yaml --testBaseURL=http://localhost:8080
APIを変更したのにapi.yamlを更新していなければ、契約テストが失敗します。
コンシューマー側の流れは次のようになります。
specmatic stub api.yaml --port=9000
コンシューマーは、同じapi.yamlに基づくスタブに対して開発できます。
この構成により、仕様は単なる古いドキュメントではなく、実装と開発を支える生きた契約になります。
スタブとモックの違いを整理したい場合は、ワークフローを設計する前に APIスタビングとモッキングの比較 を確認しておくと理解しやすいです。
後方互換性をチェックする
Specmaticには、後方互換性チェックもあります。
backward-compatibility-checkコマンドは、概念的には次の流れで動作します。
- 新しいバージョンの仕様からスタブを起動する
- 以前のバージョンの仕様からテストを生成する
- そのテストを新しいスタブに対して実行する
- 以前は動いていた契約が壊れていないか確認する
これにより、リリース前に破壊的変更を検出できます。
独立してデプロイされるマイクロサービスでは、後方互換性の破壊が障害につながりやすいため、CIに組み込む価値があります。この考え方は、双方向契約テスト で扱われるより広い概念にも近いです。
Specmaticが適合するケース
Specmaticは、次のようなチームに向いています。
- OpenAPI、AsyncAPI、GraphQL、gRPCなどの仕様をすでに持っている
- 仕様を信頼できる契約として運用したい
- プロバイダーとコンシューマーが別チームまたは別サービスである
- 仕様と実装の乖離をレビューではなくCIで検出したい
- CLIとCI中心のワークフローに抵抗がない
- スタブサーバーを仕様から自動で起動したい
一方で、次のような場合はSpecmatic単体では不足する可能性があります。
- まだAPI仕様を持っていない
- API設計をビジュアルに進めたい
- アドホックなAPIデバッグも同じツールで行いたい
- ドキュメント、テスト、モック、チームコラボレーションを1つのUIで管理したい
Specmaticは、契約エンジンに特化したツールです。そのため、CLIネイティブでシャープに動きますが、APIライフサイクル全体を管理する統合ワークスペースではありません。
この点は、Apidogのようなプラットフォーム型ツールとの違いです。
Apidogもスキーマ駆動で、OpenAPI仕様を読み込み、スキーマに対してレスポンスを検証し、コードなしで OpenAPIスキーマからモックサーバー を起動できます。
違いはスコープです。
- Specmatic: CLIネイティブの契約テスト/スタブツール
- Apidog: 設計、テスト、モック、ドキュメントを扱うビジュアルワークスペース
ただし、ApidogもPactスタイルのコンシューマー駆動型契約ブローカーではありません。チームがPactブローカーを必要としている場合、SpecmaticとApidogのどちらもその用途とは異なります。
OpenAPI仕様から実行可能なテストを生成するワークフローを見たい場合は、Apidogの OpenAPI仕様からのAPIテストコレクション生成 を確認してください。
よくある質問
Specmaticは無料ですか?
はい。コアとなる契約エンジンはオープンソースで、CLIまたはDockerから無料で利用できます。
商用版の提供もありますが、OpenAPI仕様から契約テストやスタブサーバーを実行する用途では無料で始められます。有料ティアの最新情報は、公式サイトとGitHubで確認してください。
SpecmaticはOpenAPIのみに対応していますか?
いいえ。OpenAPIが最も一般的な入り口ですが、SpecmaticはAsyncAPIもサポートしています。バージョン2.0からはGraphQLとgRPCにも対応し、さらにWSDLやAvroなどの形式もサポートしています。
どの形式でも基本モデルは同じです。仕様を実行可能な契約として扱います。
OpenAPI自体に慣れていない場合は、OpenAPI Specificationチュートリアル から始めると理解しやすいです。
SpecmaticはPactと同じですか?
同じではありません。
Pactはコンシューマー駆動です。コンシューマーが期待をブローカーに公開し、プロバイダーがそれに対して検証します。
Specmaticは契約駆動です。OpenAPIなどの仕様が単一の共有契約になり、Specmaticはその契約に対してプロバイダーを検証し、コンシューマー向けにスタブを起動します。
どちらも連携時の予期しない問題を減らすためのものですが、契約の管理方法が異なります。
SpecmaticはOpenAPI仕様を生成できますか?
はい。Specmaticは既存サービスの前段でプロキシとして動作し、実際のリクエストとレスポンストラフィックをキャプチャできます。
そのトラフィックから、OpenAPIドキュメントとサンプルファイルを生成できます。動作するサービスはあるが、まだ正式な仕様がない場合に有効です。
まとめ
Specmaticは、OpenAPIなどの仕様と実行中のサービスの乖離を検出するための契約テストツールです。
実用上の使い方はシンプルです。
# 実サービスを契約に対して検証する
specmatic test api.yaml --testBaseURL=http://localhost:8080
# 仕様からスタブサーバーを起動する
specmatic stub api.yaml --port=9000
1つの仕様ファイルから契約テストとスタブを実行できるため、プロバイダーとコンシューマーの認識を同期しやすくなります。さらに、後方互換性チェックにより、破壊的変更をリリース前に検出できます。
ターミナルとCI中心で開発し、堅牢なOpenAPI仕様を維持しているチームには、Specmaticはよく適合します。
一方で、同じOpenAPIファイルを使って、契約、テスト、モック、ドキュメントを1つのビジュアルワークスペースで扱いたい場合は、Apidogをお試しください。Apidogはスキーマに対してレスポンスを検証し、コードなしでエンドポイントをモック化し、仕様を実行可能なテストコレクションに変換できます。Apidogをダウンロード して、設計からテストまでのループを1か所で確認してください。

Top comments (0)