Files
gplan-2/game/tests/run_all.gd
T
DKChan 5f51a916d4 test(unit): T1 单元测试与契约层——七套件实跑入口落 tests/run_all.gd
- data_config: ConfigDB 表加载+跨表护栏零诊断/进度坐标 ceil-clamp 解析与警告去重/变异池门控/shop·meta 消费面/manifest↔目录同步/越域 fatal 退出码(独立进程 expect=1,deferred 触发保 quit 通道)/统一随机流(派生确定性/计数器账本/标签不参与派生/负种子归一化)
- battle_settlement: DamageMath 四纯函数(池乘区/克制分量/掷点查档/吃掷点分量)+DamageController 伤害单据五配方+B/A 双结账模式+来源敌死作废+requires 前置门+主角倒下 halt+AC 合流三通道+池 clamp 与 refresh 政策
- contracts: 五配方/三目标/双政策词表封闭+掷点标签∈RNG 封闭词表(EC12)+单据九栏缺省+增益布尔受理口径(EC1/EC2)
- 红线: 期望值全由表读值推导(零玩法数值字面量)/零自建 RNG(夹具种子仅求复现)
- 轻闸: 冒烟 557/0 + ui_input_probe 十一断言全绿(基线零漂移)
2026-09-28 02:52:19 +08:00

55 lines
2.5 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# tests/run_all.gd — 单元测试统一入口(ADR-0004 双载体的逻辑测试调用点,套件 manifest 协议 D2 AC-2b)
# 用法:godot --headless --path game --script res://tests/run_all.gd (CI 侧包装外部超时:timeout 120s …)
# 协议:套件清单逐条"套件 → 期望退出码";致命类独立进程(expect=1)。
# 执行形态(单元测试与契约层批 2026-09-28):逐套件起独立 Godot 子进程实跑
#(OS.get_executable_path() 解析本引擎二进制——--script 模式无 autoload/全局标识符,
# 每个测试文件自带显式实例化夹具,见 tests/README 协议要点)。
# 场景探针(.tscn 载体)由 CI/轻闸单独步骤调用,不经本入口。
extends SceneTree
func _init() -> void:
print("[run_all] unit/contract suite entry — %d suites" % _suites().size())
if DisplayServer.get_name() != "headless":
push_warning("[run_all] 建议以 --headless 运行(D2 冒烟协议)")
var failures := 0
for suite in _suites():
failures += _run_suite(suite)
if failures > 0:
push_error("[run_all] %d 个套件失败" % failures)
quit(1)
return
print("[run_all] all green (%d suites)" % _suites().size())
quit(0)
# 套件清单:{ "path": String, "expect": int };致命类(期望非 0)独立进程断言退出码。
func _suites() -> Array:
return [
{"path": "res://tests/unit/example_test.gd", "expect": 0},
{"path": "res://tests/unit/data_config/config_db_test.gd", "expect": 0},
{"path": "res://tests/unit/data_config/config_db_fatal_oob_test.gd", "expect": 1},
{"path": "res://tests/unit/data_config/rng_service_test.gd", "expect": 0},
{"path": "res://tests/unit/battle_settlement/damage_math_test.gd", "expect": 0},
{"path": "res://tests/unit/battle_settlement/damage_controller_test.gd", "expect": 0},
{"path": "res://tests/unit/contracts/system_contracts_test.gd", "expect": 0},
]
func _run_suite(suite: Dictionary) -> int:
var path: String = suite.get("path", "")
var expect: int = int(suite.get("expect", 0))
if path.is_empty():
push_error("[run_all] suite missing path")
return 1
var args := PackedStringArray(["--headless", "--path", ProjectSettings.globalize_path("res://"), "--script", path])
var out := PackedStringArray()
var code: int = OS.execute(OS.get_executable_path(), args, out, true, false)
var text := "\n".join(out)
print(text)
if code != expect:
push_error("[run_all] FAIL %s — 退出码 %d ≠ 期望 %d" % [path, code, expect])
return 1
print("[run_all] PASS %s (exit=%d)" % [path, code])
return 0