testing-guidelines について
testing-guidelinesは、コードベースのテスト作成と整理に関する指針です。統合テスト、分離されたテストデータ、回帰テスト、公開エントリーポイントごとのテストを重視します。
主な機能
- 01サニタイズ済みフィクスチャで外部サービスをモック
- 02統合テストを優先
- 03バグ修正に回帰テストを追加
- 04すべての公開エントリーポイントをテスト
- 05テスト状態を分離して後片付け
活用シーン
- 01新機能のテストを計画
- 02バグ修正のテストカバレッジ追加
- 03CLIコマンドやAPIルートのテスト
- 04ネットワーク呼び出しや状態共有の防止
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ getsentry/ warden --skill testing-guidelinesインストール後、Claude Code で/testing-guidelinesを入力して読み込まれたか確認します。
詳細
テストガイドライン
このコードベースのテストを作成する際は、以下の原則に従ってください。
基本原則
1. 外部サービスはモックし、実際のデータに基づくフィクスチャを使用する
サードパーティのネットワークサービスは必ずモックしてください。実際のデータに基づくフィクスチャを必ず使用してください。
- フィクスチャからは PII を取り除いてください(
[email protected]、user-123などのダミーデータを使用します) - 実際の API レスポンスを取得してから、機密情報を削除してください
- テストでは実際のネットワーク呼び出しを行わないでください
2. ユニットテストよりインテグレーションテストを優先する
実装の詳細ではなく、入力と出力を検証するエンドツーエンド形式のテストに重点を置いてください。
- 内部メソッドではなく、公開インターフェースをテストしてください
- 純粋関数のエッジケースにはユニットテストも有用ですが、インテグレーションテストを優先してください
- リファクタリングでテストが失敗しても動作に変更がない場合、そのテストは実装に依存しすぎています
3. エッジケースのテストを最小限にする
問題のあらゆるパターンをテストする必要はありません。
- 一般的なケースを十分にカバーしてください
- 入力の組み合わせを網羅するテストは省略してください
- 保守の負担が増えるだけで価値のない、起こりそうにないエッジケースは省略してください
- 通常は、入力のカテゴリごとに代表的なテストを1つ用意すれば十分です
4. バグには必ず回帰テストを追加する
バグが見つかった場合、それを検出できるテストを必ず追加してください。
- 修正前には失敗し、修正後には成功するテストにしてください
- バグの内容が分かる、説明的な名前を付けてください
- これにより、同じバグの再発を防ぎます
注記: 回帰テストの対象は、意図せず壊れた動作(バグ)であり、意図的な変更ではありません。意図的な機能の削除、非推奨化、破壊的変更には回帰テストは不要です。これらは不具合ではなく設計上の決定です。
5. ユーザー向けのすべての入口をカバーする
顧客やユーザー向けの各入口に、基本的なテストを少なくとも1つ必ず用意してください。
- CLI コマンド、API エンドポイント、公開/エクスポートされた関数
- まず一般的なケースや正常系をテストしてください
- これにより、入口が正常に動作することを確認できます
注記: 「入口」とは、エクスポートされた関数、CLI コマンド、API ルートなどの公開インターフェースを指します。ユーザー向けのフラグやオプションを処理する場合でも、内部/非公開関数は入口ではありません。入口をテストし、内部関数はそれらのテストを通じてカバーしてください。
6. 手動 QA の前にテストで検証する
手動テストの前に、機能が動作することを検証する手段がすべてテストです。
- テストは後回しにせず、コードの作成前または作成と同時に書いてください
- テストできない場合は、設計を見直してください
- テストに合格すれば、安心してリリースできる状態にしてください
技術ガイドライン
ファイル構成
- テストファイルには
*.test.tsという拡張子を使用します - テストはソースと同じ場所に配置します:
foo.ts→foo.test.ts
テストの分離
各テストでは、以下を満たす必要があります。
- 他のテストに影響を与えず、単独で実行できる
- ファイル操作には一時ディレクトリを使用する
afterEachフックでリソースをクリーンアップする
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
describe('my feature', () => {
let tempDir: string;
beforeEach(() => {
tempDir = join(tmpdir(), `warden-test-${Date.now()}`);
mkdirSync(tempDir, { recursive: true });
});
afterEach(() => {
rmSync(tempDir, { recursive: true, force: true });
});
it('does something with files', () => {
writeFileSync(join(tempDir, 'test.ts'), 'content');
// ... test code
});
});
純粋関数のテスト
副作用のない純粋関数には、特別なセットアップは必要ありません。
import { describe, it, expect } from 'vitest';
import { matchGlob } from './matcher.js';
describe('matchGlob', () => {
it('matches exact paths', () => {
expect(matchGlob('src/index.ts', 'src/index.ts')).toBe(true);
});
});
テストの実行
pnpm test # Run all tests in watch mode
pnpm test:run # Run all tests once
提出前のチェックリスト
- 新しい入口には、正常系のテストが少なくとも1つある
- バグ修正(意図的な変更を除く)には回帰テストが含まれている
- 外部サービスは、機密情報を削除したフィクスチャを使ってモックされている
- テストは実装ではなく動作を検証している
- テスト間で状態を共有していない
コメント
Markdown 対応