adventure-table

P0 — 測試指南

Phase:P0 — Character Core + SRD / Rules Foundation
本文件定義 P0 各 Subphase 如何驗收。P0-F 必須最終證明 實作規格.md 的 AC-P0-01 ~ AC-P0-10,而不是只證明「頁面打得開」。

最後更新:2026-08-29


1. 測試原則

P0 的測試證據分為:

每個 Subphase 必須先通過自己的測試再進下一個;不要把 P0-A~E 的驗證全部拖到 P0-F 才做。

測試 fixture 必須固定、可重現,不依賴人工先去 DB 改資料。

標準 fixture 保持無 Numeric Override;Override 測試由標準 fixture建立固定 variant,避免把正常規則與非標準數值混成同一基準。

三份 P0 文件的 Subphase 標題必須完全一致。


P0-A — Project Foundation

驗收目的

證明專案地基可重現啟動與測試,不在這一階段驗 Character rules。

必測

  1. Docker Compose 可啟動 P0 所需服務。
  2. PostgreSQL ready 後 backend 可連線。
  3. Alembic baseline migration 可 apply;fresh DB 不需要人工修改。
  4. FastAPI 啟動後 health/readiness 回成功。
  5. React/Vite app shell 可開啟。
  6. pytest baseline 能執行且 exit 0。
  7. Vitest baseline 能執行且 exit 0。
  8. Playwright baseline 能啟動真實 browser、開 app shell 並 exit 0。

負向/重現性

P0-A 關門

以上全綠後才進 P0-B。


P0-B — Character-Relevant SRD Foundation

對應主要契約:AC-P0-01、AC-P0-02。

Required Categories

測試 P0-B 定義的 character-relevant category 都存在、可 parse 成對應 Pydantic model 並可進 ContentRegistry:

不包含 monsters / beasts。

Monster / Beast Scope Guard

P0-B 測試必須明確證明:

Monster / Beast stat blocks 已延後 P4-A

Stable Key Uniqueness

每個 category:

Cross-reference Validation

至少驗證:

不寫 Monster-specific dangling reference 測試,因 P0 不導入 Monster data。

Negative Cases

故意注入:

預期:ContentRegistry validation fail,不能靜默略過。

Reference Query Baseline

至少能由 registry 查到 fixture 會使用的 Race / Class / Spell / Equipment / Condition entry。

P0-B 關門


P0-C — Character Core & Persistence

對應主要契約:AC-P0-03、AC-P0-04、AC-P0-08 的資料承載部分。

標準驗證角色

固定 fixture:

Human Fighter 5 / Wizard 5,Character Level 10
Class order:Fighter 1→5,再 Wizard 1→5。

Ability Scores

Ability Build Score Modifier expectation for P0-D
STR 16 +3
DEX 14 +2
CON 14 +2
INT 16 +3
WIS 10 +0
CHA 8 -1

這些是永久 Build 效果已解析後、Numeric Override 前的值。Human racial ability increase 已包含。

至少包含:

Hit Dice

Build total:

d10 × 5
d6  × 5

Initial State:

d10 available = 5
d6  available = 5

HP Progression

fixture base HP gains:

Lv1  Fighter: 10
Lv2  Fighter: 6
Lv3  Fighter: 6
Lv4  Fighter: 6
Lv5  Fighter: 6
Lv6  Wizard:  4
Lv7  Wizard:  4
Lv8  Wizard:  4
Lv9  Wizard:  4
Lv10 Wizard:  4

這是 fixture choice,不是產品強制 fixed HP。

Class Order / Multiclass Representation

fixture 必須保存:

Fighter
Fighter
Fighter
Fighter
Fighter
Wizard
Wizard
Wizard
Wizard
Wizard

測試 derive-ready structure 能得到:

P0-C 主要驗資料結構保存,正式 derived rules 在 P0-D 驗。

Ability Score Round-trip

Save / Reload 後必須仍是:

16 / 14 / 14 / 16 / 10 / 8

不得因 Reload 或重新解析 race_ref 改值。

Spell Access vs Prepared State

Build entry 至少可辨識:

State 另外保存 prepared_spell_entry_ids

至少測:

  1. Wizard spellbook entry 在 Build。
  2. 可準備的 entry 能被 State 引用。
  3. prepared → unprepared / unprepared → prepared 只改 State。
  4. Build Version id 與 canonical Build payload 不變。
  5. State 指向不存在/不可準備的 Build entry 時 validation fail。

Hit Dice Structure / Persistence

修改:

d10 available 5 → 4

預期:

Optional Roleplay

Save / Reload

流程:

Seed fixture
↓
Read Character
↓
Serialize Build + State
↓
Close transaction/session
↓
Read again
↓
Compare

結果:Build 相同、State 相同。

Build / State Isolation

先記錄 current Build Version id 與 canonical Build payload,再依序修改:

預期:

Starting Equipment 不覆寫 Live Inventory

流程:

Seed from Build starting equipment
↓
Live Inventory 產生
↓
修改/新增/移除 live Inventory
↓
Save + Reload + new application session

Reload 後必須使用最後保存的 Inventory State,不能重新從 Build Starting Equipment 洗掉玩家後來的變化。

Fresh Application Session Persistence

至少建立新的 application / DB session;不能只測同一 ORM object 留在 memory。

P0-C 關門


P0-D — Character Rules & Backend API

對應主要契約:AC-P0-02、AC-P0-05、AC-P0-08,以及 AC-P0-03/04/07 的 API 部分。

Fixed Derived Expectations

標準 fixture 預期:

Base HP = 10 + 6 + 6 + 6 + 6 + 4 + 4 + 4 + 4 + 4 = 54
CON contribution = +2 × 10 = 20
Max HP = 74
項目 預期
Total Character Level 10
Fighter Level 5
Wizard Level 5
Proficiency Bonus +4
STR Save +7
CON Save +6
Athletics +7
Arcana +7
Perception +4
Passive Perception 14
AC(Chain Mail + Shield) 18
Wizard Spell Save DC 15
Wizard Spell Attack +7
Max HP 74

Ability Modifier

至少:

8  -> -1
10 -> 0
14 -> +2
16 -> +3
18 -> +4

另驗 fixture 的 Human racial bonus不會在 Rules Engine 再套一次

Proficiency Bonus Boundaries

每區間 lower + upper 成對測:

Lv1  -> +2
Lv4  -> +2
Lv5  -> +3
Lv8  -> +3
Lv9  -> +4
Lv12 -> +4
Lv13 -> +5
Lv16 -> +5
Lv17 -> +6
Lv20 -> +6

Skill / Save

fixture:

Passive Perception

10 + Perception modifier 4 = 14

Armor Class

live Inventory:

Chain Mail equipped 16
+ Shield equipped 2
= AC 18

必測:

Spellcasting

Wizard INT 16、PB +4:

Spell Save DC = 8 + 4 + 3 = 15
Spell Attack = 4 + 3 = +7

Prepared selection 不影響基礎公式。

Max HP

標準 = 74。

另做 rules-only variant:effective CON modifier +3、無 Max HP override:

54 + (3 × 10) = 84

用來證明 74 不是 hardcode。

Numeric Override Variant

從標準 fixture 建:

ability:strength = 18
ac = 19
max_hp = 80

固定 expectation:

項目 預期
Effective STR 18
STR Modifier +4
Athletics +8
STR Save +8
AC 19
Max HP 80

另外驗:

Multiclass Spellcasting Boundary

Fighter(非 Eldritch Knight)5 對 multiclass caster level 貢獻 0,因此 fixture 不測多個 caster class aggregation。

P0-D 只驗:representation、class order、spell source/access、Build Spellbook vs State Prepared separation。

Multiclass caster-level / combined spell-slot progression 留 P1。

Reference API

至少:

GET /api/rules/content/spells
GET /api/rules/content/spells/{fireball-key}
GET /api/rules/content/classes/{fighter-key}

Character Sheet API

GET /api/characters/{fixture-id}/sheet

至少驗:

State Patch

至少測:

PATCH HP
PATCH temporary HP
PATCH prepared spells
PATCH condition list
PATCH resource usage
PATCH available hit dice
PATCH inventory quantity
PATCH inventory equipped state
PATCH inventory add/remove entry

每次:

Invalid State

至少:

預期 4xx,且 DB 不留下半套更新。

P0-D 關門


P0-E — Character Sheet & State UI

對應主要契約:AC-P0-06、AC-P0-07、AC-P0-09、AC-P0-10 的 UI 部分。

Vitest — Header

Vitest — Page 1

Vitest — Page 2

Vitest — Page 3

Component tests 使用 mock CharacterSheetDTO不要在 React test 重算 D&D 規則

Playwright — Character Sheet 基本流程

啟動 app
↓
開啟 Fighter 5 / Wizard 5 fixture
↓
看到 Header
↓
切換 Attributes / Skills
↓
看到 d10 5/5、d6 5/5
↓
切換 Spells
↓
可區分 Spellbook / Prepared
↓
切換 Inventory

Playwright — Current HP Persistence

HP 74 → 50
↓
保存成功
↓
reload browser
↓
仍為 50

Playwright — Temp HP / Condition

Temp HP 0 → 8
加入 Poisoned
↓
reload
↓
Header / Page 1 仍正確顯示

Playwright — Spell Resource

改變 spell slot 使用狀態,reload 後保持。

Prepared Spells 的 Build/State isolation 主要由 P0-C / P0-D schema、persistence、API tests 驗;P0 不為了 E2E 額外要求完整準備法術 workflow。

Playwright — Inventory Quantity

Healing Potion ×2 → ×1,reload 後保持;Build Version / Starting Equipment 不變。

Playwright — Equipped State

Shield equipped → unequipped:

Playwright — Optional Roleplay

Roleplay profile 全空時 Page 1 不報錯、不要求必填。

Playwright — P0 Independence

沒有 Room / Campaign / Session / Combat / AI 連線時,P0 Character Sheet 仍可完整操作。

P0-E 關門


P0-F — Full P0 Integration & Closeout

P0-F 對 P0-A~E 做完整 regression / integration,並建立 AC-P0-01~10 的最終證據。

Acceptance Contract 對照

Contract 主要證據
AC-P0-01 P0-B Content validation + P0-F startup regression;不含 Monster / Beast
AC-P0-02 P0-B ContentRegistry + P0-D Reference API
AC-P0-03 P0-C persistence round-trip + P0-F fresh-session regression
AC-P0-04 P0-C Build / State isolation + P0-D API mutation
AC-P0-05 P0-D rules unit tests + fixed override variant
AC-P0-06 P0-E Vitest + page navigation / Hit Dice E2E
AC-P0-07 P0-C persistence + P0-D state API + P0-E reload E2E + P0-F server restart
AC-P0-08 P0-C Fighter5/Wizard5 schema + P0-D derived tests;不含 multiclass caster aggregation
AC-P0-09 P0-D CharacterSheetDTO + P0-E frontend/E2E
AC-P0-10 P0-E standalone E2E + P0-F scope guard

每一條 contract 至少有一個可定位自動測試;人工目視不能是唯一證據。

Full Regression

至少重跑:

  1. P0-A environment / health / baseline tests。
  2. P0-B full character-relevant SRD validation + negative fixtures。
  3. P0-C full schema / persistence / Build-State isolation suite。
  4. P0-D full rules + API suite。
  5. P0-E full Vitest + Playwright suite。
  6. standard fixture fixed expectations。
  7. Numeric Override variant。
  8. fresh app / server restart persistence。
  9. Starting Equipment reload regression。
  10. Shield equipped state → AC recalculation。

Monster / Beast Deferral Regression

P0-F 必須驗證:

人工驗收

自動測試全綠後,人工快速檢查:

  1. Character Sheet 三頁閱讀性。
  2. 繁體中文 UI 文案正常;Action / Spell Slot 等關鍵字可保留英文。
  3. Fighter / Wizard features 與 spells 沒明顯混在錯誤頁。
  4. HP / Conditions 在 Header 一眼可見。
  5. Hit Dice 清楚分辨 d10 available/total 與 d6 available/total。
  6. Spellbook / Prepared 不顯示成同一概念。
  7. Inventory 顯示 live state,不因 reload 回到 starting equipment。
  8. Roleplay 空白不造成大片必填阻擋。
  9. reload 後不出現明顯「先顯示 browser 舊 authoritative state 再跳正確值」的 UX 問題。

P0 不人工驗收 Room、AI、Combat、Map、Monster stat blocks。

建議測試命令

實際 scaffold 完成後統一提供簡單命令,例如:

# Backend
pytest

# Frontend unit
npm run test

# E2E
npm run test:e2e

最終命令以實際 package scripts / project config 為準;P0-F closeout 時更新。

P0-F 關門條件

P0 可以標記完成前:

完成後才更新 PROJECT_BRIEF.md 為 P0 implementation complete,並開始規劃 P1 與 P1 Subphases。