Foundation
Development Guidelines

テスト

テスト戦略と各テストの責務・書き方のガイドライン。

方針

統合テスト + E2Eテストの2層構成を基本とする。複雑なロジックに限り、ユニットテストを追加する。

各テストの責務

統合テスト

バックエンドの全層(API → UseCase → Domain → Infrastructure)を通して、APIの入出力とデータの永続化を検証する。

検証すること

  • 各エンドポイントの正常系(期待するデータが返ること)
  • 異常系のすべてのドメインエラーパス(NOT_FOUND、CONFLICTなど)
  • DBにデータが正しく永続化されること(作成・更新・削除の結果)
  • 認証・認可(未認証で401、権限不足で403)

検証しないこと

  • 入力バリデーション(Valibotスキーマが正しければ保証されるため、二重チェックになる)
  • Infrastructure層の内部実装(SQLやDBドライバの挙動はライブラリが保証するため)
  • ビジネスロジックの全エッジケース(統合テストは実行コストが高いため、複雑な分岐はユニットテストで検証する)

E2Eテスト

ブラウザを通じて、ユーザーの操作フローが正しく動作することを検証する。

検証すること

  • 主要なユーザーフロー(壊れるとビジネスに直接影響する操作)
  • 画面遷移(リンク、フォーム送信後のリダイレクト)
  • フォーム操作の完了と結果の画面への反映
  • エラー時のユーザーへのフィードバック(代表的なケースを1つ)

検証しないこと

  • ビジネスロジックの網羅的なエッジケース(E2Eは実行コストが最も高いため、ロジックの網羅は統合テストで行う)
  • 異常系の全パターン(統合テストで網羅済みのため、E2Eでは代表的なエラー表示の確認に留める)
  • APIレスポンスの構造や値の詳細(統合テストで検証済みのため、二重チェックになる)
  • スタイリングやレイアウトの詳細(E2Eテストの範囲外であり、ビジュアルリグレッションツールで検証する)

ユニットテスト

純粋関数や複雑なビジネスロジックを、依存なしに高速に検証する。

書く場面

  • 統合テストではカバーが困難な複雑な分岐やエッジケースがある場合のみ
  • 例: 複数条件の組み合わせによる計算、日付範囲の重複判定、状態遷移ロジック

検証すること

  • 入力に対する出力の正しさ
  • 境界値・エッジケース(0、負数、空配列、null等)
  • エラーパス(不正な入力に対する例外やエラー値)

検証しないこと

  • 単純なgetter/setterやパススルー関数(ロジックがないため、テストしても信頼性が上がらない)
  • 実装の詳細(リファクタでテストが壊れる原因になるため、振る舞いのみを検証する)
  • 外部ライブラリの動作(ライブラリ側で検証済みのため、二重チェックになる)

テスト名の書き方

テスト名は、失敗したときにテスト名だけで何が壊れたかわかるように書く。

形式

  • 条件なし: {期待する振る舞い}
  • 条件あり: {条件}の場合、{期待する振る舞い}

// 統合テスト
describe('employee.create', () => {
  it('従業員を作成し、IDを返す');
  it('メールアドレスが重複している場合、CONFLICTエラーを返す');
});

// E2Eテスト
test.describe('従業員管理', () => {
  test('従業員を新規作成すると、一覧に表示される');
  test('存在しない従業員にアクセスすると、404ページに遷移する');
});

避けるべき書き方

  • 正しく動く — 何が正しいのか不明
  • エッジケースを処理する — どのケースか不明
  • createEmployee test — 英語のテスト名は日本語プロジェクトでは読みにくい

On this page