testing-unit について
testing-unitは、分離性と実行速度を重視したユニットテストのガイドを提供するスキルです。TypeScriptやPythonの開発者向けに、テスト構成、HTTPインターセプト、フィクスチャ、テストデータ生成を扱います。
主な機能
- 01Arrange-Act-Assert形式のテスト
- 02重複を避けるパラメータ化テスト
- 03フィクスチャのスコープと分離の指針
- 04ネットワーク層でのHTTPインターセプト
- 05ファクトリーとフィクスチャによるデータ管理
- 06テスト作成用スクリプト
活用シーン
- 01分離されたユニットテストの構成
- 02実APIに接続せずHTTP依存コードを検証
- 03再利用可能なテストデータとフィクスチャの作成
- 04テストファイルやMSWハンドラーのひな形作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill testing-unitインストール後、Claude Code で/testing-unitを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
test-cases.jsonchecklists/msw-setup-checklist.mdtest-data-checklist.mdvcr-checklist.mdexamples/handler-patterns.mdreferences/aaa-pattern.mdfactory-patterns.mdmsw-2x-api.mdstateful-testing.mdrules/_sections.mddata-factories.mddata-fixtures.mddata-seeding-cleanup.mdmocking-msw.mdmocking-vcr.mdunit-aaa-pattern.mdunit-fixture-scoping.mdunit-parametrized.mdscripts/create-msw-handler.mdcreate-test-case.mdcreate-test-fixture.md詳細
単体テストのパターン
分離性が高く、高速で、保守しやすい単体テストを書くための実践的なパターンです。テスト構造(AAA)、パラメーター化、フィクスチャ管理、HTTP モック(MSW/VCR)、ファクトリーを使ったテストデータの生成を扱います。
各カテゴリには、必要に応じて読み込む個別のルールファイルが rules/ に用意されています。また、参考資料、チェックリスト、スキャフォールディング用スクリプトも含まれます。
基本原則(必ず適用)
- AAA 構造:すべてのテストで Arrange-Act-Assert に従う必要があります。明確にするため、
// Arrange、// Act、// Assertのコメントを使用してください。 - 重複させず、パラメーター化する:複数の入力をテストする場合は、
test.each(TypeScript)または@pytest.mark.parametrize(Python)を使用してください。値だけを変えた同じテスト本体をコピー&ペーストしないでください。 - フィクスチャのスコープは重要です:変更可能なデータには
scope="function"(デフォルト)を使用してください。scope="module"またはscope="session"は、高コストで読み取り専用のリソース(DB エンジン、ML モデル)に限って使用してください。変更可能なデータを共有スコープにすると、テストが不安定になります。 - 速度の目標:各単体テストは 100ms 未満で実行してください。それより遅い場合は、I/O にアクセスしている可能性が高いため、モックしてください。
- ネットワークレベルでモックする:MSW(TypeScript)または VCR.py(Python)を使い、ネットワークレイヤーで HTTP をインターセプトしてください。
fetch/axios/requestsを直接モックしないでください。
クイックリファレンス
| カテゴリ | ルール | 影響度 | 使用するタイミング |
|---|---|---|---|
| 単体テストの構造 | 3 | 重大 | 単体テストを書くとき全般 |
| HTTP モック | 2 | 高 | フロントエンド/バックエンドのテストで API 呼び出しをモックするとき |
| テストデータ管理 | 3 | 中 | テストデータ、ファクトリー、フィクスチャを準備するとき |
合計: 3 カテゴリにまたがる 8 ルール、4 つの参考資料、3 つのチェックリスト、1 セットのサンプル、3 つのスクリプト
単体テストの構造
明確なフェーズと効率的な実行を備えた、分離性の高い単体テストを構成するための基本パターンです。
| ルール | ファイル | 主なパターン |
|---|---|---|
| AAA パターン | rules/unit-aaa-pattern.md | 分離性を確保した Arrange-Act-Assert |
| フィクスチャのスコープ | rules/unit-fixture-scoping.md | function/module/session スコープの選択 |
| パラメーター化テスト | rules/unit-parametrized.md | test.each / @pytest.mark.parametrize |
参考資料: references/aaa-pattern.md — チェックリスト付きの詳細な AAA 実装
HTTP モック
実際の API にアクセスせずに決定的なテストを実現する、ネットワークレベルのリクエストインターセプトです。
| ルール | ファイル | 主なパターン |
|---|---|---|
| MSW 2.x | rules/mocking-msw.md | フロントエンド(TypeScript)向けのネットワークレベルのモック |
| VCR.py | rules/mocking-vcr.md | HTTP カセットの記録/再生(Python) |
参考資料:
references/msw-2x-api.md— MSW 2.x API の全機能(ハンドラー、GraphQL、WebSocket、パススルー)references/stateful-testing.md— ステートフルテスト向けの Hypothesis RuleBasedStateMachine
チェックリスト:
checklists/msw-setup-checklist.md— MSW のインストール、ハンドラーの設定、テストの作成checklists/vcr-checklist.md— VCR の設定、機密データのフィルタリング、CI の設定
サンプル: examples/handler-patterns.md — CRUD、エラーのシミュレーション、認証フロー、ファイルアップロードのハンドラー
テストデータ管理
分離性と現実性を備えたテストデータを用意するための、ファクトリー、フィクスチャ、シーディングのパターンです。
| ルール | ファイル | 主なパターン |
|---|---|---|
| データファクトリー | rules/data-factories.md | FactoryBoy / @faker-js ビルダー |
| データフィクスチャ | rules/data-fixtures.md | 構成可能な JSON フィクスチャ |
| シーディングとクリーンアップ | rules/data-seeding-cleanup.md | DB の自動シーディングとティアダウン |
参考資料: references/factory-patterns.md — 高度なファクトリーパターン(Sequence、SubFactory、Traits)
チェックリスト: checklists/test-data-checklist.md — データ生成、クリーンアップ、分離性の検証
クイックスタート
TypeScript(Vitest + MSW)
import { describe, test, expect, beforeAll, afterEach, afterAll } from 'vitest';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { calculateDiscount } from './pricing';
// 1. Pure unit test with AAA pattern
describe('calculateDiscount', () => {
test.each([
[100, 0],
[150, 15],
[200, 20],
])('for order $%i returns $%i discount', (total, expected) => {
// Arrange
const order = { total };
// Act
const discount = calculateDiscount(order);
// Assert
expect(discount).toBe(expected);
});
});
// 2. MSW mocked API test
const server = setupServer(
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: 'Test User' });
})
);
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('fetches user from API', async () => {
// Arrange — MSW handler set up above
// Act
const response = await fetch('/api/users/123');
const data = await response.json();
// Assert
expect(data.name).toBe('Test User');
});
Python(pytest + FactoryBoy)
import pytest
from factory import Factory, Faker, SubFactory
class UserFactory(Factory):
class Meta:
model = dict
email = Faker('email')
name = Faker('name')
class TestUserService:
@pytest.mark.parametrize("role,can_edit", [
("admin", True),
("viewer", False),
])
def test_edit_permission(self, role, can_edit):
# Arrange
user = UserFactory(role=role)
# Act
result = user_can_edit(user)
# Assert
assert result == can_edit
Vitest 4.1 の機能
aroundEach / aroundAll(DB トランザクションに推奨)
各テストをセットアップ/ティアダウンでラップします。トランザクションでは、beforeEach/afterEach を個別に使うよりもすっきりします。
test.aroundEach(async (runTest, { db }) => {
await db.transaction(runTest) // auto-rollback on test end
})
test('insert user', async ({ db }) => {
await db.insert({ name: 'Alice' })
// transaction auto-rolls back — no cleanup needed
})
aroundAll は、同じ方法でスイート全体をラップします。
mockThrow / mockThrowOnce
冗長な mockImplementation(() => { throw err }) パターンを置き換えます。
const fn = vi.fn()
fn.mockThrow(new Error('connection lost')) // always throws
fn.mockThrowOnce(new Error('timeout')) // throws once, then normal
vi.defineHelper(クリーンなスタックトレース)
ヘルパー内部ではなく、呼び出し元の位置をエラー箇所として示すカスタムアサーションヘルパーです。
const assertPair = vi.defineHelper((a, b) => {
expect(a).toEqual(b) // error points to where assertPair() was CALLED
})
テストタグ
CLI でタグによってテストを絞り込みます。CI の高速実行に便利です。
// vitest.config.ts
test: {
tags: {
unit: { timeout: 5000 },
flaky: { retry: 3 },
}
}
vitest --tags-filter="unit and !flaky"
vitest --tags-filter="(unit or integration) and !slow"
エージェントレポーター
最小限の出力(失敗のみ)です。AI エージェント/CI のコンテキストで使用します。
AI_AGENT=copilot vitest # auto-detect agent mode
主な判断事項
| 判断事項 | 推奨 |
|---|---|
| テストフレームワーク(TS) | Vitest 4.1+(モダンで高速、aroundEach とテストタグに対応)または Jest(成熟したエコシステム) |
| テストフレームワーク(Python) | プラグイン(parametrize、asyncio、cov)を備えた pytest |
| HTTP モック(TS) | ネットワークレベルの MSW 2.x。fetch/axios を直接モックしないでください |
| HTTP モック(Python) | カセットを使う VCR.py。機密データをフィルタリングしてください |
| テストデータ | ハードコードされたフィクスチャよりファクトリー(FactoryBoy/faker-js)を使用 |
| フィクスチャのスコープ | 変更可能なものには scope="function"(デフォルト)を使用します。module/session はコストの高い不変リソースにのみ使用してください |
| 実行時間 | 単体テストあたり 100ms 未満。より遅い場合は外部呼び出しをモックしてください |
| カバレッジ目標 | ビジネスロジックは 90% 以上、重要なパスは 100% |
よくある間違い
- 脆いテストにつながる、公開された動作ではなく実装の詳細をテストすること
- ネットワークレベルで MSW を使わず、fetch/axios を直接モックすること(カバレッジが不完全になります)
- モジュールスコープのフィクスチャを介してテスト間で変更可能な状態を共有すること(テストが不安定になります)
- ID が重複するテストデータをハードコードすること(並列実行時にテストが競合します)
- データベースへのデータ投入後にクリーンアップしないこと(テスト間で状態が漏れます)
- モックを過剰に使うこと(コードではなくモックをテストすることになり、誤った安心感につながります)
mockThrow(err)(Vitest 4.1+)ではなく、冗長なmockImplementation(() => { throw err })で例外をモックすること
スクリプト
| スクリプト | ファイル | 目的 |
|---|---|---|
| テストケースの作成 | scripts/create-test-case.md | 自動検出したフレームワークでテストファイルのひな型を作成します |
| テストフィクスチャの作成 | scripts/create-test-fixture.md | コンテキスト検出機能付きで pytest フィクスチャのひな型を作成します |
| MSW ハンドラーの作成 | scripts/create-msw-handler.md | API エンドポイント用の MSW ハンドラーのひな型を作成します |