テストケース
テスト戦略
| テスト種別 |
対象 |
ツール |
現状 |
| 単体テスト(backend) |
純粋関数のビジネスロジック |
Vitest |
実装済み(2 ファイル) |
| 結合テスト(backend) |
API・DB 連携 |
Vitest |
未実装(test:integration スクリプトのみ存在) |
| 単体・E2E(frontend) |
画面 |
- |
未導入(テストランナーがない) |
現状のカバレッジは限定的
自動テストは backend の services/scoring.ts と services/candidate.ts(parseResponseFilter)だけを対象としている。それ以外の動作確認は Swagger UI(/docs)と画面上の手動操作に依存している。カバレッジ目標は設定されていない。
テスト実行方法
cd heineken-interview-arrange-backend
bun run test # vitest run(全体)
bun run test:unit # __tests__/unit のみ
bun run test:integration # __tests__/integration のみ(現状は対象ファイルなし)
bun run test:watch # ウォッチモード
bun run test:coverage # カバレッジ計測(v8)
bunx vitest run __tests__/unit/services/scoring.test.ts # 単一ファイル
bunx vitest run -t "should cap score at maxScore" # 単一テスト
frontend にテストランナーはない。品質ゲートは以下の 2 つ。
cd heineken-interview-arrange-frontend
bun run check-types
bun run lint
テスト設定
vitest.config.ts:
| 項目 |
値 |
environment |
node |
globals |
true(describe / it / expect を import 不要) |
include |
__tests__/**/*.test.ts |
testTimeout / hookTimeout |
10000 ms |
| カバレッジ provider |
v8(text / json / html レポーター) |
自動テストケース一覧
スコアリング(__tests__/unit/services/scoring.test.ts)
calculateScore:
| ID |
シナリオ |
期待結果 |
優先度 |
| SC-001 |
ルールが空 |
0 点を返す |
高 |
| SC-002 |
equals 条件が一致 |
ルールのスコアを加算する |
高 |
| SC-003 |
not_equals 条件 |
一致しない場合にスコアを加算する |
高 |
| SC-004 |
in 条件 |
値が候補に含まれる場合に加算する |
高 |
| SC-005 |
between 条件が範囲内 |
スコアを加算する |
高 |
| SC-006 |
between 条件が範囲外 |
0 点になる |
高 |
| SC-007 |
contains 条件(配列値) |
要素が含まれる場合に加算する |
中 |
| SC-008 |
greater_than 条件 |
閾値を超える場合に加算する |
中 |
| SC-009 |
less_than 条件 |
閾値を下回る場合に加算する |
中 |
| SC-010 |
複数ルール |
各ルールのスコアを合算する |
高 |
| SC-011 |
maxScore を超える合計 |
maxScore で頭打ちになる |
高 |
validateScoringRules:
| ID |
シナリオ |
期待結果 |
優先度 |
| SC-012 |
正しいルール構造 |
true を返す |
高 |
| SC-013 |
不正なルール構造 |
false を返す |
高 |
| SC-014 |
未定義の condition |
false を返す |
高 |
回答フィルタのパース(__tests__/unit/services/candidate.test.ts)
parseResponseFilter(候補者一覧の responseFilter クエリ):
| ID |
シナリオ |
期待結果 |
優先度 |
| CF-001 |
空文字を渡す |
undefined を返す |
高 |
| CF-002 |
undefined を渡す |
undefined を返す |
高 |
| CF-003 |
JSON として不正な文字列 |
BadRequestError を投げる |
高 |
| CF-004 |
スキーマに合わない JSON |
BadRequestError を投げる |
高 |
| CF-005 |
単一条件の配列形式 |
AND として解釈する |
高 |
| CF-006 |
複数条件の配列形式 |
すべてを AND として解釈する |
高 |
| CF-007 |
オブジェクト形式で logic: "and" |
AND として解釈する |
高 |
| CF-008 |
オブジェクト形式で logic: "or" |
OR として解釈する |
高 |
| CF-009 |
logic の省略 |
AND を既定とする |
高 |
| CF-010 |
eq 演算子 |
受理する |
中 |
| CF-011 |
neq 演算子 |
受理する |
中 |
| CF-012 |
contains 演算子 |
受理する |
中 |
| CF-013 |
in 演算子(配列値) |
受理する |
中 |
| CF-014 |
未定義の演算子 |
拒否する |
高 |
| CF-015 |
文字列の値 |
受理する |
中 |
| CF-016 |
数値の値 |
受理する |
中 |
| CF-017 |
文字列配列の値 |
受理する |
中 |
| CF-018 |
数値配列の値 |
受理する |
中 |
| CF-019 |
文字列と数値の混在配列 |
受理する |
低 |
| CF-020 |
条件が空配列 |
エラーにせず処理する |
中 |
| CF-021 |
ドットを含むフィールド名 |
ネストパスとして扱う |
中 |
| CF-022 |
日本語のフィールド名 |
正しく扱う |
高 |
| CF-023 |
値に特殊文字を含む |
正しく扱う |
中 |
手動確認が必要な範囲
自動テストが存在しないため、以下は Swagger UI(http://localhost:8080/docs)または画面上での手動確認が必要。
認証
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-101 |
Google アカウントでログインする |
トップページへ遷移し、localStorage に accessToken が入る |
高 |
| TC-102 |
未登録アカウントでログインする |
users が新規作成され、role が member になる |
高 |
| TC-103 |
トークンなしで保護 API を呼ぶ |
401 UNAUTHORIZED |
高 |
| TC-104 |
期限切れトークンで API を呼ぶ |
401(Token has expired) |
高 |
| TC-105 |
viewer で更新系 API を呼ぶ |
403 FORBIDDEN |
高 |
アレンジフロー
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-201 |
STEP1 で空き枠を算出する |
面接官の Google Calendar から枠が返る |
高 |
| TC-202 |
STEP1 で仮枠を押さえる |
仮枠が作成され、arrange_settings.step1.tentativeEventIds に保存される |
高 |
| TC-203 |
仮枠を再作成する |
既存の仮枠が削除されてから作り直される |
中 |
| TC-204 |
STEP2 でセグメントを定義して保存する |
arrange_settings.step2.segments に保存される |
高 |
| TC-205 |
STEP2 で本命/補欠を選ぶ |
project_candidates.selection_type が更新される |
高 |
| TC-206 |
STEP3 で追加質問を登録する |
arrange_settings.step3.questions に保存される |
中 |
| TC-207 |
PROTOTYPE_MODE=true で仮枠を押さえる |
カレンダーに書き込まれない |
高 |
候補者インポート
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-301 |
UTF-16LE の TSV をアップロードする |
列一覧・サンプル値・推奨マッピングが返る |
高 |
| TC-302 |
UTF-8 の TSV をアップロードする |
パースエラーとして 400 |
中 |
| TC-303 |
マッピングを指定してインポートを実行する |
201 が返り、進捗が processing になる |
高 |
| TC-304 |
既存の external_user_id を含むデータを取り込む |
重複としてカウントされ、二重登録されない |
高 |
| TC-305 |
アンケートインポートのプレビューを実行する |
フィルタ適用後の件数とサンプルが返る |
高 |
| TC-306 |
アンケートインポートを実行する |
import_logs が作られ、完了後に件数が反映される |
高 |
ステータス管理
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-401 |
not_contacted → contacted に変更する |
成功し、status_histories に 1 行追加される |
高 |
| TC-402 |
completed から他のステータスに変更する |
400 INVALID_STATUS_TRANSITION |
高 |
| TC-403 |
bounced → contacted に戻す |
成功する |
中 |
| TC-404 |
cancelled → not_contacted に戻す |
成功する |
中 |
日程調整
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-501 |
有効なトークンで公開ページを開く |
案件情報と候補者名が表示される |
高 |
| TC-502 |
期限切れトークンで開く |
is_expired: true またはエラーが返る |
高 |
| TC-503 |
希望日程を 1 件送信する |
selectedCount: 1 が返り、ステータスが scheduling になる |
高 |
| TC-504 |
希望日程を 21 件送信する |
400(バリデーションエラー) |
中 |
| TC-505 |
再度希望日程を送信する |
既存の希望日程が全置換される |
高 |
| TC-506 |
確定済みの候補者が送信する |
409 SLOT_NOT_AVAILABLE |
高 |
| TC-507 |
管理者が日程を確定する |
reservations が作成され、仮枠が確定イベントになる |
高 |
| TC-508 |
確定済みの候補者を再度確定する |
409 SLOT_NOT_AVAILABLE |
高 |
メール
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-601 |
テンプレートをプレビューする |
プレースホルダが差し込まれた結果が返る |
高 |
| TC-602 |
複数候補者へ一括送信する |
sent_count / failed_count が返り、email_logs に記録される |
高 |
| TC-603 |
candidateIds を空で送信する |
400(バリデーションエラー) |
中 |
| TC-604 |
PROTOTYPE_MODE=true で送信する |
実際のメールが送られない |
高 |
| TC-605 |
テンプレートを削除する |
過去の送信ログは残る |
中 |
Databricks 連携
| ID |
シナリオ |
期待結果 |
優先度 |
| TC-701 |
調査メタ更新バッチを dryRun で実行する |
611 調査ぶんのメタを取得し、DB に書き込まない |
高 |
| TC-702 |
調査メタ更新バッチを実行する |
databricks_surveys が upsert され、既存行が消えない |
高 |
| TC-703 |
Databricks 未設定でアンケート一覧を取得する |
503 DATABRICKS_NOT_CONFIGURED |
中 |
| TC-704 |
databricks_surveys に無い調査 ID で詳細を取得する |
404(502 にならないこと) |
高 |
| TC-705 |
数値以外の surveyId で詳細を取得する |
400 INVALID_SURVEY_ID(テーブル名に埋め込まれないこと) |
高 |
| TC-706 |
同一フィールドに複数回答があるパネルを取り込む |
配列として保持され、先頭 1 件に切り捨てられない |
高 |
| TC-707 |
改行を含む設問文で回答を絞り込む |
200 が返る(500 にならないこと) |
高 |
| TC-708 |
許可外メールドメインでログインする |
domain_not_allowed としてログイン画面に戻る |
高 |
テストを追加するとき
- 置き場所は
__tests__/unit/services/<service-name>.test.ts
- 外部依存(DB・Google API・Databricks)を持たない純粋関数から優先的に対象にする
describe はサービス名 → 関数名 → 観点の 3 階層で構成する(既存テストに倣う)
- 実行は
bunx vitest run <path> で単一ファイルを回すのが速い