| name | backend-test-writer |
| description | テスト計画(test-planner 成果物)または既存の仕様に基づいて、プロジェクト既存パターンに合わせた**単体テスト(mock 前提)**を書く。言語・フレームワーク非依存で、既存テストの構造を踏襲することを最優先する。実 DB を起こす integration test は `backend-integration-test-writer` に委譲する。「テスト書いて」「このコードのテスト追加して」などで起動。 |
Test Writer
単体テスト(unit test) を書く。プロジェクトの既存パターンに 合わせる ことを最優先。独自ルールを持ち込まない。
integration test(実 DB 起動、Handler → Repository 貫通)は別スキル backend-integration-test-writer に委譲する。計画段階で Unit / Integration の区分けがついている場合は Unit だけここで扱う。
いつ使うか
- 実装済みコードに単体テストを追加する
backend-test-planner が作った計画の Unit ケースを書く
- バグ修正の再発防止テスト(ロジック起因、DB 起因ではないもの)を書く
- DB / 外部サービスを叩くテストなら →
backend-integration-test-writer を使う
実行手順
1. 既存パターン調査
最も重要なステップ。勝手に書き始めない。
- 対象ディレクトリ付近で
*test*、*spec* を Glob
- 代表的なテストファイルを 1-2 本
Read
- 以下を抽出:
- テストランナー(jest / vitest / go test / pytest / rspec / ...)
- テストスタイル(table-driven / BDD / AAA / subtests)
- アサーション流儀(testify / chai / assert / expect)
- モック方式(mockery / jest.mock / sinon / unittest.mock)
- ヘルパー・フィクスチャの置き場所
- 命名規則(
TestXxx_Yyy / describe > it / def test_xxx)
2. 対象の確認
- 実装コードを
Read して挙動を把握
- 入出力・副作用・エラー条件を列挙
- 仕様書 (
docs/spec/) があれば該当セクションも参照
3. テストケース整理
backend-test-planner の成果物がある場合はそれに従う。ない場合は最低限:
- Happy path: 主要な成功パス 1-2 件
- Error path: 主なエラー条件 1-2 件
- Edge: 境界値 1 件
過剰にケースを増やさない。書きすぎると壊れやすく、価値の低いテストが増える。
4. 実装
以下を守る:
- 既存テストと同じ構造(関数定義、セットアップ、検証の順序)
- 命名は既存に合わせる
- 新しい依存を入れない(既存のアサーションライブラリで書く)
- 新しいテストランナーを導入しない
- テストヘルパーは既存を探してから作る
テストが読みやすいかを意識:
- 1 テスト = 1 振る舞いの検証
- セットアップが長い場合は共通化を検討(既存ヘルパー優先)
- マジックナンバーは意味のある定数名で
5. 実行確認
- テストを実行して緑になることを確認
- わざと壊してレッドになることも確認(書いただけでパスし続けるテストは無価値)
- カバレッジ計測ツールがあれば参考として見る(数値目標にはしない)
6. レビュー可能性
コミット時に以下を意識:
- 実装とテストを同一コミットにするか、別コミットにするか(プロジェクト慣習に従う)
- 既存テストに影響が出ていないかを
git diff で確認
アンチパターン
- ❌ 実装をそのまま書き写したテスト(処理手順のコピペ。何も検証していない)
- ❌ 過剰なモック(本来のロジックが消えてしまう)
- ❌ フラグで分岐する巨大テスト(1 テスト = 1 振る舞いを守る)
- ❌ 時刻・乱数・外部サービスに直接依存(モック・固定値を使う)
- ❌ プロダクションコードに
if testing 的な特別扱いを入れる
言語別の参考
汎用スキルなので具体の実装は既存パターンに任せるが、参考までに:
- Go:
func TestXxx(t *testing.T) / table-driven / t.Run サブテスト
- TypeScript:
describe / it / expect(jest/vitest)
- Python:
pytest の関数ベース / parametrize でテーブル駆動
- Ruby: RSpec の
describe / context / it
プロジェクトの既存パターンが最優先。上記は参考。
関連