adventure-table

P1 — 測試指南

Phase:P1 — Character Builder Complete
本文件定義 P1 各 Subphase 如何驗收。P1-H 必須最終證明 實作規格.md 的 AC-P1-01 ~ AC-P1-12,而不是只證明「Wizard 可以按下一步」。

最後更新:2026-08-29


1. 測試原則

P1 的測試證據分為:

每個 Subphase 必須先通過自己的測試再進下一個;不要把 P1-A~G 的驗證全部拖到 P1-H。

所有 Builder fixture 必須 deterministic、可程式建立,不依賴人工先在 UI 建角色。

測試必須分清:

Draft legality
Build compile result
Current State seed / reconciliation
Character Sheet derived result

不能只 assert HTTP 200can_confirm=true

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


P1-A — Builder Domain & Draft Foundation

對應主要契約:AC-P1-01、AC-P1-11、AC-P1-12 的基礎。

Draft Schema / Partial State

至少測:

  1. Create Draft 可以只有最小 identity / target level 等 partial input。
  2. 缺 Race / Class / Ability 等時 Draft 本身仍可 Save。
  3. 同一 Draft進行 full validation 時回 blocking_error,而不是 Pydantic parse整份 Draft失敗。
  4. Draft payload extra / malformed field依正式 schema被拒絕。
  5. Draft mode / source character / base version組合非法時被拒絕。

Draft Persistence

流程:

Create Draft
↓
PATCH partial choices
↓
close DB / app session
↓
GET Draft

預期:

Cancel

Create Draft
↓
Save
↓
Cancel / DELETE

預期:

Validation Result

至少有固定案例分別產生:

每筆 issue assertion:

Choice ID Stability

同一 Draft / same source:

GET
reload server-side view
GET again

Choice ID必須一致。

修改不相關欄位(例如 Character name)也不能導致所有 choice ids重生。

Draft Revision(若實作)

若採 optimistic revision:

P0 Regression

P1-A 每次 CI 至少重跑:

P1-A 關門


P1-B — Character Creation Basics

對應主要契約:AC-P1-02、AC-P1-11。

Character Workshop API / UI

至少驗:

Race / Subrace

針對 SRD content fixture至少驗:

Background

Production SRD 5.1 目前只有 Acolyte,因此測試必須把『內容只有一筆』和『Builder 機制只能處理一筆』分開。

至少:

Standard Array

測試:

具體 Standard Array數字以 P1 rules data / test fixture為準,不在本指南複製規則表。

Point Buy

至少:

Manual Input

至少:

Ability Source Ordering

固定 fixture驗:

base generation
+ race/subrace permanent grants
= resolved Build score

P1-D後再增加 ASI / Feat。

Character Sheet重新計算時不再加 race grant第二次。

Starting Skills / Proficiencies

至少測:

Vitest

至少覆蓋:

Playwright

Real backend:

/characters
→ Create Character
→ 填 Name / Target Level
→ Race / Background
→ Ability method
→ Save
→ browser reload

reload後所有輸入與已選 reference保留。

P1-B 關門


P1-C — Class Progression & Multiclass

對應主要契約:AC-P1-03、AC-P1-04。

Ordered Progression

建立 deterministic scenarios:

Fighter 1→5
Fighter 1→5 → Wizard 1→5
Wizard 1 → Fighter 1 → Wizard 2...

每個 scenario assert:

Direct High-level Create

UI直接 Target Level 10仍必須有 10 個 progression nodes。

禁止只送:

fighter=5, wizard=5

卻無法知道順序。

Starting Class Grants

至少以兩個不同 class順序驗:

Fighter → Wizard
Wizard → Fighter

預期 starting saves / proficiencies等依 Lv1 class不同;後加入 class只取得 multiclass grants。

Multiclass Prerequisite

至少:

Subclass Timing

每個代表 class至少測:

Automatic Features

到達 level後:

HP — First Character Level

驗:

HP — Later Levels

至少:

HP Alignment

len(hp_progression) == len(class_progression) == character_level

修改中間 level後 compile / reload仍保持1:1。

Downstream Invalidation

流程:

建合法 Lv10 Draft
↓
修改 Lv3 class

預期:

Playwright

至少一條:

Create target Lv10
→ level rail逐級選 Fighter 5 / Wizard 5
→ 選 subclass
→ 設 HP methods
→ reload

assert rail順序與已填資料保留。

P1-C 關門


P1-D — ASI, Feat & Structural Choices

對應主要契約:AC-P1-05。

ASI Timing by Class Level

建立 multiclass scenario,讓 total level與某 class ASI timing不同。

assert:

ASI Cumulative Data Trap

直接使用 production levels.json 的 Fighter level rows 驗 cumulative semantics:

Fighter Lv4: cumulative 1, previous 0 → delta 1 → 1 個 ASI/Feat node
Fighter Lv5: cumulative 1, previous 1 → delta 0 → 0 個 node
Fighter Lv6: cumulative 2, previous 1 → delta 1 → 1 個 ASI/Feat node

必測負向:

ASI Structural Validation

至少測:

Feat

以 SRD可用 Feat fixture:

Numeric Override + Prerequisite

固定案例:

calculated ability不足 prerequisite
→ feat fail

加入合法 Numeric Override使 effective ability達標
→ feat pass

另驗:

Numeric Override
→ 不能讓 Lv1 Fighter提早選 Lv3 subclass
→ 不能創造額外 ASI occurrence
→ 不能把 choose 2改成 choose 3

Generic Choice Resolver

對目前 SRD實際存在的 choice shapes做 parameterized tests:

測試應由 representative content entries驅動,不只手刻 dummy object。

Selection Trace / Provenance(若實作)

若 Build新增 builder trace:

UI / E2E

至少一條高等 Fighter:

progress to ASI level
→ 選 ASI
→ Summary能力更新
→ 改成 Feat
→ prerequisite提示
→ Review未來可讀

P1-D 關門


P1-E — Spellcasting Progression

對應主要契約:AC-P1-06、AC-P1-10 的 spell state部分。

Representative Spell Fixtures

至少建立:

  1. Wizard — Spellbook + Prepared。
  2. Prepared caster — Cleric或Druid。
  3. Known caster — Sorcerer / Bard / Ranger代表。
  4. Two-source multiclass caster — 驗 combined slots。
  5. Wizard / Warlock或其他含 Warlock組合 — 驗 Pact Magic分池。

Wizard Spellbook

至少:

Wizard Prepared

Prepared Caster

驗:

若 P1-E調整 Prepared schema,必須加入 P0 Wizard fixture compatibility test。

Known Caster

Always Prepared / Granted

至少一個 subclass / feature來源:

Same Spell Different Source

建立同一 spell由兩個 source取得的 scenario:

Multiclass Spell Slot Progression

使用固定 progression scenarios比對 D&D 5e 2014 rules data預期。

至少含:

不要只測一個 Lv10數字;測 boundary / floor behavior。

Pact Magic

Resource Capacity Invariant

若 State維持 used + remaining

若 migration成usage-only:

P1-E 關門


P1-F — Equipment, Review & Character Creation

對應主要契約:AC-P1-07、AC-P1-08、AC-P1-11。

Equipment Choice Shapes

從實際 SRD class data挑 representative nested options,至少覆蓋:

每個 scenario assertion:

No Starting Gold Path

P1 UI / API標準 Builder:

Starting Equipment Compile

assert:

Initial Inventory

Create Confirm後:

Build Starting Equipment
→ initial State inventory

assert第一次一致。

接著:

remove / add / quantity / equip state mutation
→ reload

assert live Inventory保持最後 State,不由 Build重新洗回。

Initial HP / Hit Dice / Resources

Create Confirm fixture:

Review DTO

至少測:

Confirm Atomicity

故意在不同階段造成失敗:

預期每次:

Version 1 Metadata Baseline

P1-F migration / Create Confirm至少驗:

Double Submit / Idempotency

快速重複 Confirm:

Full Create Playwright

至少一條 non-caster與一條 caster:

/characters
→ Create
→ 完整 Wizard
→ Review
→ Confirm
→ /characters/:id
→ reload

assert Character Sheet關鍵摘要與 Builder Review一致。

P1-F 關門


P1-G — Level Up & Character Versions

對應主要契約:AC-P1-09、AC-P1-10。

Version Metadata Continuity

P1-F 已完成 schema migration / legacy backfill;P1-G 驗證後續版本沿用同一 metadata contract:

Level Up Draft

建立既有 Character:

current version N
↓
create level_up draft

assert:

Level Up Confirm

assert:

Cancel

Level Up Draft Cancel:

Stale Base

流程:

Create Draft A from v3
Create Draft B from v3
Confirm B -> v4
Confirm A

A必須被拒絕 stale_build_version;不可建立覆蓋v4的v5 based on stale data。

HP Reconciliation

固定案例:

old current/max = 30/40
new max = 48

預期:

38/48

另測:

Spell Slot / Resource Reconciliation

固定 usage fixture:

capacity下降 correction:

Hit Dice Reconciliation

普通升級:

multiclass切換不同 hit die:

correction total下降:

Prepared Reconciliation

Scenario A:新 Build仍允許既有 prepared → 完整保留。

Scenario B:Build correction移除 spell access → prepared變非法:

使用者修正 prepared choice後才可 Confirm。

Inventory / Conditions Preservation

Level Up前先建立非初始 Current State:

Level Up Confirm後assert上述保持,除非明確 invariant需要調整。

Version History

API / UI:

Correction

流程:

current v4
→ Correct Build Draft
→ Confirm
→ v5 correction

assert:

P1-G 關門


P1-H — Full P1 Integration & Closeout

P1-H 對應 AC-P1-01 ~ AC-P1-12 全部。

Full Backend Regression

至少跑:

pytest

包含:

Content / Rules Data Validation

Alembic

必須驗:

  1. fresh DB從零升到 head。
  2. P0 schema升到 P1 head。
  3. deterministic P0 fixture在 migration後仍可 load。
  4. P1 Draft / version metadata tables正常。

Frontend

npm install / ci
TypeScript build
Vitest

至少覆蓋:

Playwright — Create Lv1

完整 real backend:

Workshop
→ Create Lv1
→ Race / Background
→ Ability
→ Class / choices
→ Equipment
→ Review
→ Confirm
→ Sheet
→ reload

Playwright — Direct High-level Multiclass

至少一條 target high level:

Confirm後讀 Character Sheet與Version 1。

Playwright — Level Up

Open existing character
→ Level Up
→ Add class level
→ choices
→ reconciliation preview
→ Confirm
→ Sheet
→ Version History

Browser Reload Draft Persistence

在 Builder中途 reload:

Server Restart Persistence

PostgreSQL full stack:

Create Draft / Character
↓
restart backend
↓
reload

Draft / Character / Version / Current State全部從 DB回復,不依賴 process memory。

P0 Character Sheet Regression

既有 P0 fixture:

Representative P1 Fixtures

至少有以下 categories 的 deterministic acceptance:

Scenario 驗證重點
Lv1 non-caster starting grants / ability / equipment / initial State
High-level Fighter subclass / ASI / Feat / HP progression
High-level Wizard spellbook / prepared / slots
Prepared caster prepared eligibility / State separation
Known caster known progression / replacement
Fighter / Wizard class order / P0 compatibility
two-source caster multiclass combined slots / source separation
Warlock multiclass Pact Magic pool separation

具體數值存 test fixtures / rules data,文件不建立第二份規則表。

Negative Full-flow Cases

至少從 API層嘗試繞過 UI:

全部必須 Server拒絕且不留下 partial commit。

Manual Smoke

至少人工檢查:

  1. Character Workshop desktop。
  2. Create Builder desktop。
  3. Create Builder mobile width。
  4. Level rail可讀性。
  5. searchable long spell/equipment selector。
  6. Review warnings / non-standard values清楚。
  7. Level Up reconciliation preview可理解。
  8. Version History不讓人誤以為是HP存檔。
  9. Confirm後 Character Sheet銜接自然。

P1-H 關門條件

只有以下全部成立才可進 P2:

P1-H 關門後才開始依當時 codebase規劃 P2 Subphases。