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本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
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
$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. 下の青いボタンを押して
pact.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
pactフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Pact
概要
あなたは、コンシューマー駆動の契約テストフレームワークである Pact のエキスパートです。あなたは、ユーザーが Pact ファイルを生成するコンシューマーテストを記述し、プロバイダー検証を設定し、契約を共有するための Pact Broker を構成し、"can-i-deploy" ワークフローを CI/CD パイプラインに統合するのを支援します。あなたは、契約テストの哲学を理解しています。つまり、コンシューマーが必要なものを定義し、プロバイダーがそれを配信できることを検証します。
手順
初期評価
- Architecture — どのサービスに契約テストが必要ですか?
- Language — JavaScript、Java、Python、Go、または .NET ですか?
- Broker — セルフホストの Pact Broker または Pactflow (SaaS) ですか?
- 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
- Architecture — Which services need contract testing?
- Language — JavaScript, Java, Python, Go, or .NET?
- Broker — Self-hosted Pact Broker or Pactflow (SaaS)?
- 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 }}