Back to skills
SKILL.md
Write Api Case
ASecurityAPIの統合テストのケースを、公開契約(仕様・OpenAPI・承認済みの仕様書・機能一覧)を根拠に、DBや外部APIをモックしたVitestのテストとして書き、e2eと共有の対応表と機能一覧に載せる。対象はSvelteKitの+server.ts・actionsとHonoのルート。落ちたケースは、意図した変更による呼び出し方の壊れなら直し、製品の退行や期待する結果の失敗なら直さずに報告する。対応表でAPIの対象に受け持つケースがないとき、画面から呼ばれないAPIや権限・不正な入力・上流のエラーを確かめるとき、'このAPIのテストを書いて'、'APIのケースを足して'、'/write-api-case'で使う。
- 92 stars
- 0 votes
- 0 copies
- 0 views
- Added November 11, 2026
Works with
Security analysis
100/100npx -y skills add nokonoko1203/agent-settings --skill write-api-case --agent claude-codeAre you the author of Write Api Case?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/nokonoko1203-write-api-case)---
name: write-api-case
description: "APIの統合テストのケースを、公開契約(仕様・OpenAPI・承認済みの仕様書・機能一覧)を根拠に、DBや外部APIをモックしたVitestのテストとして書き、e2eと共有の対応表と機能一覧に載せる。対象はSvelteKitの+server.ts・actionsとHonoのルート。落ちたケースは、意図した変更による呼び出し方の壊れなら直し、製品の退行や期待する結果の失敗なら直さずに報告する。対応表でAPIの対象に受け持つケースがないとき、画面から呼ばれないAPIや権限・不正な入力・上流のエラーを確かめるとき、'このAPIのテストを書いて'、'APIのケースを足して'、'/write-api-case'で使う。"
---
# APIのケースを書いて直す
APIの入口(SvelteKitの`+server.ts`の関数と`actions`、Honoのルート)を、DB・外部APIなど外部との境界をモックしたうえでテストから呼び、応答と境界に残った結果を確かめる。テストはVitestで書き、e2eと同じ対応表(`~/.claude/references/verification-map.md`)に`runner: "api"`のケースとして載せる。
APIのケースは画面のe2eを補うもので、置き換えない。利用者が画面から行う操作は、`write-e2e-case`で画面のケースを持つ。APIのケースで受け持つのは、画面から呼ばれないAPI、画面では組み合わせが多すぎる不正な入力・権限・上流のエラー、そして画面のケースでは見えない境界への書き込みの中身である。
前提は、プロジェクトに検証スキル(`.claude/skills/verify-<app>/`)と対応表があり、CIで対応表を照合していること(`verify-map check --ledger`と`--api-tests`)。揃わなければ、AIがケースを足す条件(`CLAUDE.md`の「調査と検証」)を満たさない。その場合はケースを足さず、候補を示して人に選んでもらう(`spec`)か、`/create-e2e-ci`で対応表とCIの照合を整えることを提案する。
## 1. 書く対象を決める
次のどれかから、1回に扱う対象を決める。
- `verify-map check --ledger`が「受け持つケースも例外もない」と出した`api:`・`action:`の対象
- 機能一覧で`手動`や`未確認`の札が付いた、APIで観測できるサブ機能
- ユーザーが名指ししたAPI
APIのケースが`covers`に持てるのは`api:`と`action:`だけである。`ui:`・`route:`・`link:`・`call:`は画面の対象なので、e2eで受け持つ。
## 2. 期待値を契約から決める
期待する結果の根拠は、公開契約に限る。
- ユーザーの指示、承認済みの仕様書、OpenAPIなどのAPIの仕様、機能一覧、既存の公開契約(型として公開した入出力、文書化された状態コード)
今の実装の応答を正解の根拠にしない。不具合があれば、それがそのまま正解になるためである。根拠が見つからないもの、根拠どうしが食い違うものは書かずに、`仕様確認`として報告に回す。
ケースごとに、次の観点(`aspects`)から当たるものを決める。
| 観点 | 確かめること |
|---|---|
| `normal` | 正しい要求に、契約どおりの状態コードと本文が返る |
| `persist` | 書き込んだあとに、別の要求で読み返すと変わっている。読み返すAPIがなければ、モックの保存先が受けた書き込みの中身 |
| `invalid-input` | 不正な入力に、契約どおりの拒否(状態コードと理由)が返り、モックの保存先も外部APIのモックも何も受けていない |
| `error` | 上流(DB・外部API)の失敗に、契約どおりの応答が返り、途中まで書いたものが残らない |
| `empty` | データがないときの応答 |
| `auth` | 認証がない、または権限のない利用者が拒否され、情報が返らず、何も変わらない |
書き込みの対象(`POST`・`PUT`・`PATCH`・`DELETE`の`api:`と`action:`)は、e2eとAPIのケースを合わせて、`persist`と`invalid-input`をそろえる。
## 3. 書き起こす
### 置き場所と形
- テストは`*.test.ts`にし、確かめるルートと同じフォルダーか、`src/tests/`に置く。抽出器はどちらも確認対象から外す
- 1ケース1本のテストにし、ケースIDのタグを1つ付ける(`test('…', { tags: ['@case:<id>'] }, async () => { … })`)。`describe`には付けない。ケースIDは、e2eのケースと名前空間を共有する
- Vitestの設定は`strictTags: false`にする。ケースIDのタグを設定に宣言せずに使うためである。`include`は`src/**/*.test.ts`などに絞り、Playwrightのテスト(`e2e/`の`*.spec.ts`)を拾わないようにする。拾うと、読み込みに失敗したファイルとして照合で落ちる
- 同じ変更で、`scenarios.json`にケース(`runner: "api"`、`covers`、`aspects`)を足し、確かめるサブ機能の札を`[api: <id>]`にする。サブ機能の一部だけなら範囲付きの札にし、残りの範囲には`e2e`・`手動`・`未確認`の札を残す
### 呼び方
- **Hono**: `app.request(path, init, env)`で呼ぶ。サーバーは起動しない。Cloudflare Workersのbindingsなどは第3引数でモックを渡す
- **SvelteKit**: `+server.ts`の`GET`・`POST`などや、`+page.server.ts`の`actions`をimportし、イベント(`request`・`params`・`url`・`locals`・`cookies`)を組み立てて呼ぶ。組み立てる関数は`src/tests/`に1つ置いて使い回す。この呼び方では`hooks.server.ts`を通らない。hooksで行う認証や`locals`の設定は、APIのケースで確かめたことにならない。hooksの振る舞いは、画面のe2eか、`handle`を呼ぶ別のケースで受け持つ
内部の関数やsetterを直接呼んで代用しない。入口を通らないと、入力の検証や認可の抜けを見逃す。
### モック
DB・外部API・ファイル置き場・時刻・乱数など、外部との境界は既定ですべてモックする。
- 境界のモジュール(DBのクライアント、外部APIのクライアント)を`vi.mock`で差し替える。プロジェクトに既存のモック(e2e用のモック、フィクスチャ)があれば使い、二重に作らない
- DBのモックはメモリ上の保存先にし、テストごとに作り直す(`beforeEach`)。テストどうしで状態を共有しない
- 外部APIのモックは、受けた要求を記録し、`invalid-input`・`auth`では何も受けていないことを確かめる
- 本物のDBや外部サービスにはつながない。モックで確かめたことを、実際の接続や認証の証拠にしない
## 4. 確かめる
次の3つが揃わないケースは足さない。
1. **通る**: 足したケースを繰り返し動かし、すべて通る(目安は10回。`vitest run <file> --repeats=9 --retry=0`)。1回でも落ちたら原因を直す。直せなければ、今回書いたテストは残さずに外し、ケースを`pending`(`reason`に理由)にして、サブ機能の札を`[未確認: 理由]`に戻し、もう一度下の3で照合する
2. **条件を確かめている**: 期待値を1つ変えると落ちることを、ケースごとに確かめて元に戻す。落ちないテストは条件を確かめていない
3. **整合する**: APIのテストを全件動かした結果(`--reporter=json --outputFile=<file>`)で、`verify-map check`(`--ledger`・`--api-tests`・`--api-results`)が不整合なし。足したケースだけを動かして照合するなら、`--cases <動かしたケースID>`を付ける。どちらで照合したかと、動かしたケースを証拠に書く
結果は`evidence.md`の「e2eの結果」の表に、ケース、確かめた範囲、繰り返した回数、期待値を変えた確認を書く(`~/.claude/references/evidence.md`)。足したケースは報告でも一覧にする。
## 5. 落ちたケースを直す
まずエラーと差分を読み、原因を次のどれかに分ける。
| 原因 | 見分け方 | 扱い |
|---|---|---|
| 呼び出し方の壊れ | パスや入力の形が合わない、モックの差し替え先が見つからない。その原因が、承認された変更か、今の作業での意図した変更にある(パスを変えた、モジュールを分けた) | AIが直してよい。同じ契約(同じ入口に、同じ意味の入力を送る)を保ったまま書き直し、4で確かめる |
| 製品の退行 | 入口が消えた、契約にある入力を受け付けなくなった。その原因が意図した変更にない | テストを直さない。製品の不具合として報告し、`playbook`の不具合の修正に回す |
| 期待する結果の失敗 | 呼び出しは通り、assertionが期待値と違う値を見た | 直さない。不具合なら`playbook`の不具合の修正に回し、契約の変更なら、期待値の変更をユーザーに承認してもらう |
呼び出し方の壊れか製品の退行か分からないときは、製品の退行として扱い、どの変更が原因かを報告する。
- 期待値を弱めて通さない。`expect`を消す、範囲を広げる、再試行を増やす、のどれも、承認なしに行わない。`test.skip`や`test.todo`にはしない
- 機能を消して確認対象がなくなったケースは、対応表と一緒に消してよい。それ以外の削除は承認を得る
## やらないこと
- 画面のe2eのケースを、APIのケースで置き換えること。画面の経路はe2eで確かめる
- 本物のDBや外部サービスにつなぐこと
- タグのないテスト(ユニットテスト)を足すこと。`CLAUDE.md`の規則どおり、ユニットテストのケースはユーザーが示す
- 既存のケースの期待値を、承認なしに変えること
Attribution
Related skills
View all in ai-agents →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.