Skip to content
Published on

API契約テスト & APIツーリング 2026年版ディープダイブ: Pact、Bruno、Hoppscotch、MSW、Karate DSL、Schemathesis 完全比較

Authors

2026年のAPIツール事情: なぜ再び契約テストなのか

2026年のAPIツール界隈には大きな変化が二つある。まず、2023年のPostmanのSaaS全面シフト以降、オフラインファーストかつオープンソースのBrunoやHoppscotchがエンタープライズ採用を急加速させた。次に、OpenAPI 3.1とAsyncAPI 3.0が安定し、スキーマファーストのワークフローが再び主流となり、Pact型のCDC(Consumer-Driven Contracts)がポリグロット・マイクロサービスの標準セーフティネットとして定着した。本稿では11個のツールを実コードと共に比較する。

契約テストが解く本当の問題

従来の結合テストは二つのサービスを同時に立ち上げる必要があった。サービスが50を超えるとCIは1時間を超え、あるチームのデプロイが他チームを止める。契約テストは「消費者が期待するレスポンス」と「供給者が実際に返すレスポンス」を独立に検証し、共通の契約ファイルを介して合意する。ThoughtWorks Tech Radarが2018年からPactを"Adopt"に置き続ける理由はここにある。

Pact: CDCの標準になった理由

PactはRealestate.com.auで生まれ、2013年にOSS化された最も成熟したCDCフレームワークである。JS、Java、.NET、Go、Python、Rust、PHP、Swift、Kotlinのクライアントがあり、Pact Brokerが契約を一元管理する。2026年時点でPact仕様v4はメッセージング(Kafka、RabbitMQ)とGraphQLを第一級でサポートする。

// consumer-pact.test.js — Jest + @pact-foundation/pact v15
import { PactV4, MatchersV3 } from '@pact-foundation/pact'
import path from 'path'
import { OrderClient } from '../src/order-client.js'

const { like, integer, decimal, iso8601DateTime } = MatchersV3

const provider = new PactV4({
  consumer: 'web-checkout',
  provider: 'order-service',
  dir: path.resolve(process.cwd(), 'pacts'),
  logLevel: 'warn',
})

describe('Order API contract', () => {
  it('returns order details', async () => {
    await provider
      .addInteraction()
      .given('order 42 exists')
      .uponReceiving('a request for order 42')
      .withRequest('GET', '/orders/42', (b) => b.headers({ Accept: 'application/json' }))
      .willRespondWith(200, (b) =>
        b.jsonBody({
          id: integer(42),
          total: decimal(199.99),
          createdAt: iso8601DateTime('2026-05-01T10:00:00Z'),
          items: like([{ sku: 'ABC-1', qty: integer(2) }]),
        })
      )
      .executeTest(async (mockServer) => {
        const client = new OrderClient(mockServer.url)
        const order = await client.fetch(42)
        expect(order.total).toBe(199.99)
      })
  })
})

消費者側テストがパスすると、pacts/web-checkout-order-service.jsonが生成されPact Brokerにpublishされる。供給者はpact-provider-verifierでその契約を実コードに対し再検証する。

Pact Brokerとcan-i-deploy

Pact Brokerは単なるファイル置き場ではない。要となる機能はcan-i-deployコマンドで、どのバージョンの消費者・供給者が、どの環境に共存可能かをマトリクスで算出する。PactFlowがSaaS、Pact Broker OSSがセルフホスト版だ。韓国の大手フィンテックTossは自社Pact Brokerを運用し、50超のマイクロサービス間の契約を管理していることをSLASH 2024で公開した。

MSW: ブラウザとNodeを一括モック

MSW(Mock Service Worker)はService Worker APIとNodeのhttpインターセプタを用い、ネットワーク層で直接モックする。すなわちアプリコードを一行も変えず、本物のfetch/XHR呼び出しを横取りする。2024年のv2から2026年GAの@mswjs/sourceを使えばOpenAPI仕様からハンドラを自動生成できる。

// src/mocks/handlers.js — MSW v2
import { http, HttpResponse, delay } from 'msw'

export const handlers = [
  http.get('https://api.example.com/orders/:id', async ({ params }) => {
    await delay(100)
    if (params.id === '404') {
      return new HttpResponse(null, { status: 404 })
    }
    return HttpResponse.json({
      id: Number(params.id),
      total: 199.99,
      items: [{ sku: 'ABC-1', qty: 2 }],
    })
  }),
  http.post('https://api.example.com/orders', async ({ request }) => {
    const body = await request.json()
    return HttpResponse.json({ id: 99, ...body }, { status: 201 })
  }),
]

MSW vs Pact: 競合ではなく補完関係

「MSWがあればPactは要らない」というのはよくある誤解だ。両者は別の問題を解く。MSWは消費者側の開発・UIテスト向けの一時的モック、Pactは消費者と供給者間の契約を永続化し、双方の合意を検証する。理想的な組合せはPactのインタラクションからMSWハンドラを自動生成することで、メルカリのエンジニアリングブログが2024年にこのパターンを公開している。

Bruno: オフラインファーストのPostman代替

Brunoは2023年に登場し、v2(2025年)でエンタープライズ機能を一通り備えたOSS APIクライアントだ。最大の差別点は「コレクションがGitに入るファイル」であること。JSONではなくBru構文を使うのでdiffがきれいで、クラウド同期なしにチーム協業できる。

# users/get-by-id.bru — Bruno collection file
meta {
  name: Get user by id
  type: http
  seq: 1
}

get {
  url: {{baseUrl}}/users/{{userId}}
  body: none
  auth: bearer
}

auth:bearer {
  token: {{accessToken}}
}

vars:pre-request {
  userId: 42
}

assert {
  res.status: eq 200
  res.body.id: eq 42
  res.body.email: matches /.+@.+\..+/
}

tests {
  test("user has expected role", function() {
    expect(res.getBody().role).to.equal("admin")
  })
}

Hoppscotch: ブラウザネイティブのOSS APIワークベンチ

Hoppscotch(旧Postwoman)はPWAとして動作するフルスタックAPIクライアントだ。REST、GraphQL、WebSocket、SSE、MQTT、Socket.IOを単一UIで扱える。2024年からHoppscotch CloudとSelf-hosted Enterprise Editionが分離され、GDPR配慮が必要なチームほどセルフホストを選ぶ。SmartHRがGraphQLスキーマ探索の社内標準としてHoppscotchを採用した事例を公開している。

Karate DSL: BDDスタイルでJavaコード不要のAPIテスト

KarateはIntuitが作ったJavaベースのAPIテストフレームワークだが、ユーザーはJavaを一行も書かない。Gherkin構文でREST、GraphQL、性能テスト(Karate Gatling)、UIテスト(Karate UI)までカバーする。2026年のv1.5はGraalVM Native Imageを公式サポートし、CI起動時間を約80%短縮した。

Feature: Order API contract

Background:
  * url 'https://api.example.com'
  * header Accept = 'application/json'

Scenario: get order returns expected schema
  Given path 'orders', 42
  When method get
  Then status 200
  And match response ==
    """
    {
      id: 42,
      total: '#number',
      createdAt: '#regex .+T.+Z',
      items: '#[] #object'
    }
    """

Scenario: create order
  Given path 'orders'
  And request { sku: 'ABC-1', qty: 2 }
  When method post
  Then status 201
  And match response.id == '#number'

Schemathesis: OpenAPIから自動生成されるプロパティベーステスト

SchemathesisはHypothesisの上に構築されたPythonツールだ。OpenAPI/SwaggerまたはGraphQLスキーマを入力として、自動的に数千のエッジケースを生成する。「妥当な入力に対し5xxを返してはならない」「レスポンスは必ずスキーマに一致する」といった不変条件を検証する。

# Schemathesis CLI 基本利用
pip install schemathesis

schemathesis run \
  --checks all \
  --workers 8 \
  --hypothesis-deadline 1000 \
  --report \
  https://api.example.com/openapi.json

# CIで特定エンドポイントだけを高速に
schemathesis run \
  --include-path-regex '^/orders' \
  --max-examples 50 \
  --base-url https://staging.example.com \
  ./openapi.yaml

GitLab、Spotify、BoseがSchemathesisを採用したことを公表しており、韓国ではカカオエンタープライズが2024年に社内APIゲートウェイ回帰に導入した。

Dredd: MarkdownとOpenAPIで直接回すテスト

DreddはApiaryが作った最古参のOpenAPIテストツールの一つだ。API BlueprintまたはOpenAPI 2.0/3.0文書を読み、各example(例)を実APIに対し呼び出してレスポンスを検証する。シンプルだが「ドキュメントが嘘をついていない」を強制する用途には強力だ。2026年現在、活発な開発は減っているが安定しているとの評価。

Prism: StoplightのOpenAPIモックサーバ

PrismはOpenAPI 3.x文書を即座にHTTPモックサーバへ変換する。バックエンドが未完成でもフロントエンドはリアルなレスポンスを得られる。prism mock openapi.yamlだけで起動でき、example型とdynamic型の両方をサポートする。SchemathesisとPrismを組み合わせれば、バックエンド無しでOpenAPI仕様自体を回帰テストできる強力なパターンになる。

RestAssured: Java界の事実上の標準

RestAssuredはJava/Groovyベースの統合テストライブラリで、JUnit 5やTestNGと自然に統合する。Spring Boot Test、WireMock、TestContainersと組合せれば、マイクロサービスの結合シナリオを一つのテストファイルに収められる。KarateがBDDなら、RestAssuredはコードファーストだ。

PostmanとInsomnia: SaaS世代の現在

Postmanはv11(2024年)でPostman AIを追加し、SaaS依存をさらに深めた。Insomnia(Kong所有)は2024年のライセンス変更が炎上し、Insomniumというフォークが生まれた。両者とも強力だが、コレクションがクラウドに紐付き、セルフホスト方針も限定的なため、金融・公共領域ではBrunoやHoppscotchへの移行が加速した。

OpenAPI 3.1: 何が変わったのか

OpenAPI 3.1はJSON Schema 2020-12と100%整合した。最大の破壊的変更はnullableキーワードが廃止され、type: ["string", "null"]のような正式JSON Schema表現になったこと。またwebhooksオブジェクトが追加され、インバウンドコールバックAPIも第一級で文書化できる。

openapi: 3.1.0
info:
  title: Order Service
  version: 2.0.0
paths:
  /orders/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
webhooks:
  orderShipped:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShippedEvent'
      responses:
        '200':
          description: Webhook received
components:
  schemas:
    Order:
      type: object
      required: [id, total]
      properties:
        id:
          type: integer
        total:
          type: number
        cancelReason:
          type: ['string', 'null']

AsyncAPI 3.0: イベント駆動APIのOpenAPI

AsyncAPI 3.0は2023年12月にGAされ、OpenAPIと同じスキーマファースト思想をKafka、RabbitMQ、MQTT、WebSocket、AMQPに広げた。3.0の核心はチャネルと操作(operation)の分離で、同一チャネルの送受信方向を明確に文書化できる。MicrocksとEventCatalogがAsyncAPIベースのモックブローカとカタログを提供する。

GraphQLスキーマテスト

GraphQLはSDL自体が契約に近いため、契約テストとの相性は良い。しかし「レスポンスがスキーマと一致する」と「クエリがBFFのビジネス要求を満たす」は別物だ。Apollo GraphOSのschema-check、GraphQL Inspector、PactのGraphQLプラグインがそれぞれ別の階層で答えを提供する。

CDC vs 結合テスト vs スキーマ検証

この三つはよく混同される。スキーマ検証(Dredd、Schemathesis、Prism)は「仕様自体が整合しレスポンスが仕様に一致するか」。契約テスト(Pact)は「消費者が実際に依存している部分を供給者が壊していないか」。結合テストは「二つのサービスを本物で立ち上げ端から端まで通るか」。CDCは結合テストの99%を置き換え得るが、0%は常に必要だ。

CI統合パターン: Pact + GitHub Actions

name: api-contract
on: [push, pull_request]
jobs:
  consumer-contract:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run test:pact
      - name: Publish pacts
        if: github.ref == 'refs/heads/main'
        env:
          PACT_BROKER_BASE_URL: https://broker.example.com
          PACT_BROKER_TOKEN: $PACT_TOKEN
        run: npx pact-broker publish ./pacts --consumer-app-version=$GITHUB_SHA --branch=main
      - name: Can I deploy
        run: npx pact-broker can-i-deploy --pacticipant web-checkout --version $GITHUB_SHA --to-environment production

ツール選定マトリクス

ツールカテゴリOSSRESTGraphQLメッセージング強み
PactCDCYesYesYesYes双方向契約、Broker
MSWモックYesYesYesNoブラウザ+Node統合
BrunoクライアントYesYesYesWSGit親和
HoppscotchクライアントYesYesYesWS/MQTT/SSEPWA、多プロトコル
KarateE2EYesYesYesKafkaBDD DSL
SchemathesisファジングYesYesYesNoプロパティベース生成
Dredd仕様検証YesYesNoNoシンプル
PrismモックサーバYesYesNoNoOpenAPIから即時
RestAssuredコードテストYesYesYesNoJUnit統合
PostmanSaaSクライアントNoYesYesWS/gRPC巨大エコシステム
InsomniaSaaSクライアント一部YesYesgRPC洗練UI

韓国/日本の事例: Toss、カカオ、メルカリ、サイボウズ

Tossは50超のマイクロサービス環境でPact + Pact Brokerを標準化し、can-i-deployの結果を自社SlackボットでチームへPushしている(SLASH 2024)。カカオエンタープライズはカカオワークのAPI回帰テストにSchemathesisを導入した。メルカリはメッセージキュー基盤のCDCのためにPact MessageとKarate Kafkaを組合せた。サイボウズはkintoneの公開APIドキュメントをOpenAPI 3.1へ全面移行する際、外部開発者向けにPrismモックサーバをホスティングしている。

アンチパターン: やってはいけないこと

第一に、Pactを結合テストとして使わないこと。Pactは両サービスを同時に立ち上げる前提では意味を失う。第二に、OpenAPI仕様がコードと乖離したまま手書き運用されると、契約テスト自体が嘘になる。tRPC、Zod、openapi-fetchといった型ファーストツールで仕様とコードを同期させること。第三に、Schemathesisを本番環境に当てないこと。必ずstagingまたは隔離環境で。

ポリグロット環境の標準スタック案

2026年現実的な標準: フロントエンド開発・UIテストはMSW、消費者-供給者の契約はPact + Pact Broker、OpenAPI仕様の回帰はSchemathesis、バックエンド未完成時のモックはPrism、日常的なAPI探索はBruno(Git親和)またはHoppscotch(PWA)、E2EはKarateまたはRestAssured。Postmanは外部パートナーデモ専用に限定する。

マイグレーション チェックリスト

PostmanからBrunoへ: Bruno CLIのimport postman-collectionコマンドでコレクションを変換。環境変数はbruファイルのvarsブロックへ移行される。WireMockからMSWへ: スタブマッピングをMSWハンドラへ1対1自動変換するツールはまだないので手作業を計画。DreddからSchemathesisへ: 単純なexample検証を超えてプロパティベースへ拡張するなら--checks allから始める。OpenAPI 3.0から3.1へ: nullable: truetype: ["string","null"]へ置換。openapi-formatツールが変換を自動化する。

結論: 契約をコードのように扱う

API契約テストの本質は「仕様がコードと同時に変わり、コードと同時に検証される」点にある。2026年のツール事情は十分に成熟した。欠けているのはツールではなく、チームの合意だ。消費者が何を期待し、供給者が何を保証し、その境界を誰が記録するか。PactでもSchemathesisでも、ツールはその合意を永続的に記録するだけだ。

References