jpskill.com
🛠️ 開発・MCP コミュニティ

pact

Pactは、マイクロサービス間の連携を消費者主導契約テストで検証したい場合に、契約内容を定義し、提供者側の検証を自動化することで、システム連携の信頼性を高めるSkill。

📜 元の英語説明(参考)

When the user wants to implement consumer-driven contract testing between microservices using Pact. Also use when the user mentions "pact," "contract testing," "consumer-driven contracts," "CDC testing," "provider verification," or "Pact Broker." For API mocking, see mockoon or wiremock.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Pactは、マイクロサービス間の連携を消費者主導契約テストで検証したい場合に、契約内容を定義し、提供者側の検証を自動化することで、システム連携の信頼性を高めるSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pact.zip https://jpskill.com/download/15226.zip && unzip -o pact.zip && rm pact.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15226.zip -OutFile "$d\pact.zip"; Expand-Archive "$d\pact.zip" -DestinationPath $d -Force; ri "$d\pact.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して pact.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → pact フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Pact

概要

あなたは、コンシューマー駆動の契約テストフレームワークである Pact のエキスパートです。あなたは、ユーザーが Pact ファイルを生成するコンシューマーテストを記述し、プロバイダー検証を設定し、契約を共有するための Pact Broker を構成し、"can-i-deploy" ワークフローを CI/CD パイプラインに統合するのを支援します。あなたは、契約テストの哲学を理解しています。つまり、コンシューマーが必要なものを定義し、プロバイダーがそれを配信できることを検証します。

手順

初期評価

  1. Architecture — どのサービスに契約テストが必要ですか?
  2. Language — JavaScript、Java、Python、Go、または .NET ですか?
  3. Broker — セルフホストの Pact Broker または Pactflow (SaaS) ですか?
  4. CI — サービスはどのようにデプロイされますか?独立したパイプラインですか?

コンシューマーテスト (JavaScript)

// tests/consumer.pact.test.ts — コンシューマー側の Pact テストです。
// コンシューマーが user-service API に期待するものを定義します。
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import { resolve } from 'path';
import { UserApiClient } from '../src/api/userClient';

const { like, eachLike, string, integer } = MatchersV3;

const provider = new PactV3({
  consumer: 'order-service',
  provider: 'user-service',
  dir: resolve(__dirname, '../pacts'),
});

describe('User API - Consumer Tests', () => {
  it('should return user by ID', async () => {
    await provider
      .given('a user with ID 1 exists')
      .uponReceiving('a request for user 1')
      .withRequest({
        method: 'GET',
        path: '/api/users/1',
        headers: { Accept: 'application/json' },
      })
      .willRespondWith({
        status: 200,
        headers: { 'Content-Type': 'application/json' },
        body: like({
          id: integer(1),
          name: string('Jane Doe'),
          email: string('jane@example.com'),
        }),
      })
      .executeTest(async (mockServer) => {
        const client = new UserApiClient(mockServer.url);
        const user = await client.getUser(1);
        expect(user.id).toBe(1);
        expect(user.name).toBeDefined();
        expect(user.email).toBeDefined();
      });
  });

  it('should return 404 for non-existent user', async () => {
    await provider
      .given('no user with ID 999 exists')
      .uponReceiving('a request for non-existent user')
      .withRequest({
        method: 'GET',
        path: '/api/users/999',
      })
      .willRespondWith({
        status: 404,
        body: like({ error: string('User not found') }),
      })
      .executeTest(async (mockServer) => {
        const client = new UserApiClient(mockServer.url);
        await expect(client.getUser(999)).rejects.toThrow('User not found');
      });
  });
});

プロバイダー検証

// tests/provider.pact.test.ts — プロバイダー側の検証テストです。
// user-service がすべてのコンシューマーからの契約を満たしていることを検証します。
import { Verifier } from '@pact-foundation/pact';
import { resolve } from 'path';
import { startApp } from '../src/app';

describe('User Service - Provider Verification', () => {
  let server: any;

  beforeAll(async () => {
    server = await startApp(3456);
  });

  afterAll(async () => {
    await server.close();
  });

  it('should fulfill all consumer contracts', async () => {
    const verifier = new Verifier({
      providerBaseUrl: 'http://localhost:3456',
      provider: 'user-service',
      pactUrls: [resolve(__dirname, '../pacts/order-service-user-service.json')],
      stateHandlers: {
        'a user with ID 1 exists': async () => {
          await seedDatabase({ id: 1, name: 'Jane Doe', email: 'jane@example.com' });
        },
        'no user with ID 999 exists': async () => {
          await clearDatabase();
        },
      },
    });

    await verifier.verifyProvider();
  });
});

Pact Broker 統合

// tests/provider-broker.pact.test.ts — Pact Broker に対するプロバイダー検証です。
// ローカルファイルではなく、Broker から契約を取得します。
import { Verifier } from '@pact-foundation/pact';

const verifier = new Verifier({
  providerBaseUrl: 'http://localhost:3456',
  provider: 'user-service',
  pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
  pactBrokerToken: process.env.PACT_BROKER_TOKEN,
  publishVerificationResult: process.env.CI === 'true',
  providerVersion: process.env.GIT_COMMIT,
  providerVersionBranch: process.env.GIT_BRANCH,
  consumerVersionSelectors: [
    { mainBranch: true },
    { deployedOrReleased: true },
  ],
});

Can-I-Deploy

# can-i-deploy.sh — サービスをデプロイしても安全かどうかを確認します。
# Pact Broker にクエリを実行して、すべての契約が満たされていることを検証します。

# コンシューマーがデプロイできるかどうかを確認します
npx pact-broker can-i-deploy \
  --pacticipant order-service \
  --version $(git rev-parse HEAD) \
  --to-environment production \
  --broker-base-url $PACT_BROKER_BASE_URL \
  --broker-token $PACT_BROKER_TOKEN

# デプロイメントを記録します
npx pact-broker record-deployment \
  --pacticipant order-service \
  --version $(git rev-parse HEAD) \
  --environment production \
  --broker-base-url $PACT_BROKER_BASE_URL \
  --broker-token $PACT_BROKER_TOKEN

CI 統合

# .github/workflows/pact-consumer.yml — コンシューマー契約テストパイプラインです。
# コンシューマーテストを実行し、Pact を Broker に公開し、can-i-deploy を確認します。
name: Consumer Contract Tests
on: [push]
jobs:
  pact:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test -- --testPathPattern=pact
      - name: Publish pacts
        run: |
          npx pact-broker publish pacts/ \
            --consumer-app-version ${{ github.sha }} \
            --branch ${{ github.ref_name }} \
            --broker-base-url ${{ secrets.PACT_BROKER_URL }} \
            --broker-token ${{ secrets.PACT_BROKER_TOKEN }}
      - name: Can I deploy?
        run: |
          npx pact-broker can-i-deploy \
            --pacticipant order-service \
            --version ${{ github.sha }} \


(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Pact

Overview

You are an expert in Pact, the consumer-driven contract testing framework. You help users write consumer tests that generate pact files, set up provider verification, configure a Pact Broker for sharing contracts, and integrate the "can-i-deploy" workflow into CI/CD pipelines. You understand the contract testing philosophy: consumers define what they need, providers verify they can deliver.

Instructions

Initial Assessment

  1. Architecture — Which services need contract testing?
  2. Language — JavaScript, Java, Python, Go, or .NET?
  3. Broker — Self-hosted Pact Broker or Pactflow (SaaS)?
  4. CI — How are services deployed? Independent pipelines?

Consumer Test (JavaScript)

// tests/consumer.pact.test.ts — Consumer-side Pact test.
// Defines what the consumer expects from the user-service API.
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import { resolve } from 'path';
import { UserApiClient } from '../src/api/userClient';

const { like, eachLike, string, integer } = MatchersV3;

const provider = new PactV3({
  consumer: 'order-service',
  provider: 'user-service',
  dir: resolve(__dirname, '../pacts'),
});

describe('User API - Consumer Tests', () => {
  it('should return user by ID', async () => {
    await provider
      .given('a user with ID 1 exists')
      .uponReceiving('a request for user 1')
      .withRequest({
        method: 'GET',
        path: '/api/users/1',
        headers: { Accept: 'application/json' },
      })
      .willRespondWith({
        status: 200,
        headers: { 'Content-Type': 'application/json' },
        body: like({
          id: integer(1),
          name: string('Jane Doe'),
          email: string('jane@example.com'),
        }),
      })
      .executeTest(async (mockServer) => {
        const client = new UserApiClient(mockServer.url);
        const user = await client.getUser(1);
        expect(user.id).toBe(1);
        expect(user.name).toBeDefined();
        expect(user.email).toBeDefined();
      });
  });

  it('should return 404 for non-existent user', async () => {
    await provider
      .given('no user with ID 999 exists')
      .uponReceiving('a request for non-existent user')
      .withRequest({
        method: 'GET',
        path: '/api/users/999',
      })
      .willRespondWith({
        status: 404,
        body: like({ error: string('User not found') }),
      })
      .executeTest(async (mockServer) => {
        const client = new UserApiClient(mockServer.url);
        await expect(client.getUser(999)).rejects.toThrow('User not found');
      });
  });
});

Provider Verification

// tests/provider.pact.test.ts — Provider-side verification test.
// Verifies that user-service fulfills the contracts from all consumers.
import { Verifier } from '@pact-foundation/pact';
import { resolve } from 'path';
import { startApp } from '../src/app';

describe('User Service - Provider Verification', () => {
  let server: any;

  beforeAll(async () => {
    server = await startApp(3456);
  });

  afterAll(async () => {
    await server.close();
  });

  it('should fulfill all consumer contracts', async () => {
    const verifier = new Verifier({
      providerBaseUrl: 'http://localhost:3456',
      provider: 'user-service',
      pactUrls: [resolve(__dirname, '../pacts/order-service-user-service.json')],
      stateHandlers: {
        'a user with ID 1 exists': async () => {
          await seedDatabase({ id: 1, name: 'Jane Doe', email: 'jane@example.com' });
        },
        'no user with ID 999 exists': async () => {
          await clearDatabase();
        },
      },
    });

    await verifier.verifyProvider();
  });
});

Pact Broker Integration

// tests/provider-broker.pact.test.ts — Provider verification against Pact Broker.
// Fetches contracts from the broker instead of local files.
import { Verifier } from '@pact-foundation/pact';

const verifier = new Verifier({
  providerBaseUrl: 'http://localhost:3456',
  provider: 'user-service',
  pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
  pactBrokerToken: process.env.PACT_BROKER_TOKEN,
  publishVerificationResult: process.env.CI === 'true',
  providerVersion: process.env.GIT_COMMIT,
  providerVersionBranch: process.env.GIT_BRANCH,
  consumerVersionSelectors: [
    { mainBranch: true },
    { deployedOrReleased: true },
  ],
});

Can-I-Deploy

# can-i-deploy.sh — Check if it's safe to deploy a service.
# Queries the Pact Broker to verify all contracts are satisfied.

# Check if consumer can deploy
npx pact-broker can-i-deploy \
  --pacticipant order-service \
  --version $(git rev-parse HEAD) \
  --to-environment production \
  --broker-base-url $PACT_BROKER_BASE_URL \
  --broker-token $PACT_BROKER_TOKEN

# Record deployment
npx pact-broker record-deployment \
  --pacticipant order-service \
  --version $(git rev-parse HEAD) \
  --environment production \
  --broker-base-url $PACT_BROKER_BASE_URL \
  --broker-token $PACT_BROKER_TOKEN

CI Integration

# .github/workflows/pact-consumer.yml — Consumer contract test pipeline.
# Runs consumer tests, publishes pacts to broker, checks can-i-deploy.
name: Consumer Contract Tests
on: [push]
jobs:
  pact:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test -- --testPathPattern=pact
      - name: Publish pacts
        run: |
          npx pact-broker publish pacts/ \
            --consumer-app-version ${{ github.sha }} \
            --branch ${{ github.ref_name }} \
            --broker-base-url ${{ secrets.PACT_BROKER_URL }} \
            --broker-token ${{ secrets.PACT_BROKER_TOKEN }}
      - name: Can I deploy?
        run: |
          npx pact-broker can-i-deploy \
            --pacticipant order-service \
            --version ${{ github.sha }} \
            --to-environment production \
            --broker-base-url ${{ secrets.PACT_BROKER_URL }} \
            --broker-token ${{ secrets.PACT_BROKER_TOKEN }}