> ## Documentation Index
> Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
> Use this file to discover all available pages before exploring further.

# Testable snippets

# テスト可能なドキュメントスニペットの書き方

このガイドでは、AdCP ドキュメントに記述したコード例を自動テストで検証する方法を説明します。

## なぜドキュメントスニペットをテストするのか

ドキュメントの例を自動テストすることで、次のことが保証されます。

* 例が最新の API に追随します
* コードスニペットが記載どおりに動作します
* 破壊的変更を即座に検知できます
* ドキュメントへの信頼性が高まる

**重要**: テスト基盤は、ドキュメントファイル（`.md` と `.mdx`）内のコードブロックを **そのまま** 検証します。フロントマターで `testable: true` を付けると、そのページ内のすべてのコードブロックが抽出され実行されます。

## ページをテスト対象にします

ページ全体をテスト対象にするには、フロントマターに `testable: true` を追加します。

```markdown theme={null}
---
title: get_products
testable: true
---

# get_products

...all code examples here will be tested...
```

**重要な原則**: ページは完全にテスト可能であるか、まったくテストしないかのどちらかです。テスト可能と非テスト可能なコードブロックが混在するページはサポートしません。

### コードブロックの例

ページに `testable: true` を付けると、すべてのコードブロックが実行されます。

````markdown theme={null}
```javascript
import { testAgent } from '@adcp/client/testing';

const products = await testAgent.getProducts({
  brief: 'Premium athletic footwear with innovative cushioning',
  brand_manifest: {
    name: 'Nike',
    url: 'https://nike.com'
  }
});

console.log(`Found ${products.products.length} products`);
```
````

### Snippet Metadata

ローカルの前提条件を必要とする例には、スニペットメタデータを使います。

````markdown theme={null}
```bash requires-env=ADCP_AUTH_TOKEN
uvx adcp https://test-agent.adcontextprotocol.org/sales/mcp get_products '{}' --auth $ADCP_AUTH_TOKEN
```

```javascript integration=true
// Runs only when snippet integration tests are enabled.
```
````

`requires-env=NAME` は、名前付き環境変数が設定されていないときにスニペットをスキップします。`integration=true` は、デフォルトのローカル実行でスニペットをスキップします。それらの例は `node tests/snippet-validation.test.cjs --integration` または `SNIPPET_INTEGRATION=true` で実行します。

### テストヘルパーの活用

簡潔な例を示す場合は、クライアントライブラリに含まれるテストヘルパーを使ってください。

**JavaScript:**

```javascript theme={null}
import { testAgent, testAgentNoAuth } from '@adcp/client/testing';

// Authenticated access
const fullCatalog = await testAgent.getProducts({
  brief: 'Premium CTV inventory'
});

// Unauthenticated access
const publicCatalog = await testAgentNoAuth.getProducts({
  brief: 'Premium CTV inventory'
});
```

**Python:**

```python theme={null}
import asyncio
from adcp.testing import test_agent, test_agent_no_auth

async def example():
    # Authenticated access
    full_catalog = await test_agent.simple.get_products(
        brief='Premium CTV inventory'
    )

    # Unauthenticated access
    public_catalog = await test_agent_no_auth.simple.get_products(
        brief='Premium CTV inventory'
    )

asyncio.run(example())
```

## ベストプラクティス

### 1. テストエージェントの認証情報を使います

例には常にパブリックテストエージェントを使用してください。

* **Test Agent URL**: `https://test-agent.adcontextprotocol.org`
* **MCP Token**: `1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ`
* **A2A Token**: `L4UCklW_V_40eTdWuQYF6HD5GWeKkgV8U6xxK-jwNO8`

### 2. 例は自己完結させる

テスト対象のスニペットは次を満たしてください。

* 必要な依存関係をすべてインポートします
* 接続を初期化します
* 完結した処理を実行します
* 目に見える出力を返す（console.log など）

**良い例:**

```javascript theme={null}
// Example of a complete, testable snippet
import { AdcpClient } from '@adcp/client';

const client = new AdcpClient({
  agentUrl: 'https://test-agent.adcontextprotocol.org/mcp',
  protocol: 'mcp',
  bearerToken: '1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ'
});

const products = await client.getProducts({
  promoted_offering: 'Nike Air Max 2024'
});

console.log('Success:', products.products.length > 0);
```

**悪い例（不完全）:**

```javascript theme={null}
// Don't mark this for testing - it's incomplete
const products = await client.getProducts({
  promoted_offering: 'Nike Air Max 2024'
});
```

### 3. Use sandbox accounts

状態を変更する操作（作成・更新・削除）を示すときは、サンドボックスアカウント参照を使います。

```javascript theme={null}
// Example using sandbox account — no real campaign created
const mediaBuy = await client.createMediaBuy({
  account: {
    brand: { domain: 'acme-corp.com' },
    operator: 'acme-corp.com',
    sandbox: true
  },
  product_id: 'prod_123',
  budget: 10000,
  start_date: '2025-11-01',
  end_date: '2025-11-30'
});

console.log('Sandbox media buy created:', mediaBuy.media_buy_id);
```

### 4. 非同期処理を扱います

JavaScript/TypeScript の例では `await` または `.then()` を使用してください。

```javascript theme={null}
// Using await (recommended)
const products = await client.getProducts({...});

// Or using .then()
client.getProducts({...}).then(products => {
  console.log('Products:', products.products.length);
});
```

### 5. 例は焦点を絞る

各スニペットでは 1 つの概念のみを示してください。

```javascript theme={null}
// 良い例: 認証を示す
import { AdcpClient } from '@adcp/client';

const client = new AdcpClient({
  agentUrl: 'https://test-agent.adcontextprotocol.org/mcp',
  protocol: 'mcp',
  bearerToken: '1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ'
});

console.log('Authenticated:', client.isAuthenticated);
```

## テスト可能としてマークしないケース

次のようなドキュメントページには `testable: true` を付けるべきではありません。

### 1. 疑似コードや概念例を含むページ

実行を想定していない概念的な例が含まれている場合:

```javascript theme={null}
// Conceptual workflow - not actual code
const result = await magicFunction(); // ✗ Not a real function
```

### 2. 不完全なコード断片を含むページ

説明のために部分的なコードスニペットを示している場合:

```javascript theme={null}
// Incomplete fragment showing field structure
budget: 10000,
start_date: '2025-11-01'
```

### 3. 設定/スキーマ例を含むページ

JSON スキーマや設定構造を示すドキュメントの場合:

```json theme={null}
{
  "product_id": "example",
  "name": "Example Product"
}
```

### 4. レスポンス例を含むページ

API レスポンス（リクエストではなく）の例を示すページ:

```json theme={null}
{
  "products": [
    {"product_id": "prod_123", "name": "Premium Display"}
  ]
}
```

### 5. テスト可能・非テスト可能なコードが混在するページ

実行可能なコードと概念的なコードが混在する場合はページを分割してください。

* 完全に実行可能な例を載せたページに `testable: true`
* 概念的/部分的な例だけのページにはフラグを付けない

**注意**: テスト可能にしたページではすべてのコードブロックが実行されます。1 つでも実行できないブロックがある場合はテスト可能にしないでください。

## スニペットテストの実行

### ローカルで実行

ドキュメントのスニペットをすべてテスト:

```bash theme={null}
npm test
```

スニペットテストだけを実行:

```bash theme={null}
node tests/snippet-validation.test.js
```

このコマンドは以下を行います。

1. `docs/` 配下の `.md` と `.mdx` をすべて走査
2. フロントマターに `testable: true` があるページを検出
3. それらのページから **すべての** コードブロックを抽出
4. 各スニペットを実行して結果を報告
5. 失敗した場合はエラー終了

### Coverage Reporting

スキーマ裏付けの JSON 例と実行可能スニペットがどこに集中しているかを見るには、ドキュメント例カバレッジレポートを使います。

```bash test=false theme={null}
npm run docs:example-coverage
```

レポートは `docs/` をスキャンし、次を表示します。

* `$schema` を含み、したがって `npm run test:json-schema` でカバーされる JSON ブロック
* `$schema` のない完全な JSON ブロック
* `npm run test:snippets` でカバーされる実行可能な JavaScript、TypeScript、Python、シェルのスニペット
* 未検証の JSON または未テストの実行可能スニペットのギャップが最も大きいトップファイル

CI ダッシュボードや保存済みベースライン用に、機械可読な出力を出します。

```bash test=false theme={null}
npm run --silent docs:example-coverage -- --json
```

GitHub のジョブサマリー用に、Markdown を出します。

```bash test=false theme={null}
npm run --silent docs:example-coverage -- --markdown
```

スキーマ検証は、ワイヤープロトコルが拡張可能な場所では拡張フィールドを受け入れます。スキーマ裏付けのドキュメント例を未知の公開的なフィールドについて監査するには、次を実行します。

```bash test=false theme={null}
npm run docs:json-field-audit
```

フィールド監査はデフォルトでアドバイザリです。`scripts/docs-json-field-audit-baseline.json` に対して意図的にラチェットするときのみ `--check` を使います。

```bash test=false theme={null}
npm run docs:json-field-audit -- --check
```

意図的に検出事項をクリーンアップするときは、同じ変更でベースラインをリフレッシュします。

```bash test=false theme={null}
npm run docs:json-field-audit -- --update-baseline
```

### CI/CD での実行

スニペットテストを含むフルテストスイートは次で実行できます。

```bash theme={null}
npm run test:all
```

このコマンドには次が含まれます。

* スキーマ検証
* 例の検証
* スニペット検証
* TypeScript の型チェック

## サポート言語

現在テストでサポートされている言語:

* **JavaScript** (`.js`, `javascript`, `js`)
* **TypeScript** (`.ts`, `typescript`, `ts`) - compiled to JS
* **Bash** (`.sh`, `bash`, `shell`) - only `curl` commands
* **Python** (`.py`, `python`) - requires Python 3 installed

### 制約

**パッケージ依存**: 外部パッケージ（`@adcp/client` や `adcp` など）をインポートするスニペットが動作するのは、次のいずれかを満たす場合のみです。

1. パッケージがリポジトリの `node_modules` にインストールされています
2. もしくは `devDependencies` にパッケージが記載されています

クライアントライブラリが必要な例では、次の選択肢があります。

* **オプション 1**: ライブラリを `devDependencies` に追加し、テストでインポートできるようにします
* **オプション 2**: そのスニペットをテスト可能にしない（概念的な例として記載します）
* **オプション 3**: 依存関係のない curl/HTTP の例をテスト可能なドキュメントとして使います

## テスト失敗時のデバッグ

スニペットテストが失敗した場合は次を確認してください。

1. **エラーメッセージを確認** - どのファイルの何行目で失敗したかが表示されます
2. **手動で実行** - コードをコピーしローカルで実行します
3. **テストエージェントへのアクセス確認** - [https://test-agent.adcontextprotocol.org](https://test-agent.adcontextprotocol.org) を確認
4. **依存関係を確認** - すべての import が利用可能か確認
5. **スニペットを見直す** - 自己完結しているか検証

Example error output:

```
Testing: quickstart.mdx:272 (javascript block #6)
  ✗ FAILED
    Error: Cannot find module '@adcp/client'
```

これは `@adcp/client` パッケージのインストールが必要であることを示しています。

## 貢献ガイドライン

新しいドキュメントを追加するときは次を守ってください。

1. ✅ すべてのコードブロックが実行可能ならページ全体に `testable: true` を付ける
2. ✅ シンプルな例にはクライアントライブラリのテストヘルパーを使います
3. ✅ コミット前にローカルでスニペットをテストする（`npm test`）
4. ✅ 例は自己完結かつ完全な形にします
5. ✅ 例ではテストエージェントの認証情報を使います
6. ❌ 不完全な断片が 1 つでもあるページをテスト可能にしません
7. ❌ 疑似コードを含むページをテスト可能にしません
8. ❌ 同じページにテスト可能コードと非テスト可能コードを混在させない
9. ❌ 例に本番用の認証情報を使わない

## 質問がありますか？

* `docs/quickstart.mdx` にある既存のテスト可能な例を確認します
* テストスイートを確認します: `tests/snippet-validation.test.js`
* [Slack コミュニティ](https://join.slack.com/t/agenticads/shared_invite/zt-3c5sxvdjk-x0rVmLB3OFHVUp~WutVWZg) で質問します
