Files
hello-godot/tests/bomb_test.gd
T

155 lines
4.5 KiB
GDScript

extends SceneTree
## 炸弹系统回归测试(时间驱动):
## 初始 2 枚 → 引爆清敌清弹-1 → 用尽 → 空仓无效 → Boss 击破 +1
## → B 道具拾取 +1 → 上限 5
## 输入映射层:fire 含 J、bomb 含 K
## 运行:godot --headless -s tests/bomb_test.gd
const GLOBAL_TIMEOUT := 25.0
var _phase := 0
var _phase_time := 0.0
var _time := 0.0
var _game: Game
var _fails: Array[String] = []
func _initialize() -> void:
_game = (load("res://scenes/game.tscn") as PackedScene).instantiate()
root.add_child(_game)
print("[bomb_test] game instantiated")
func _fail(msg: String) -> void:
_fails.append(msg)
print("[FAIL] " + msg)
func _next_phase() -> void:
_phase += 1
_phase_time = 0.0
func _finish() -> bool:
if _fails.is_empty():
print("[bomb_test] PASS")
else:
print("[bomb_test] FAIL: %d issue(s)" % _fails.size())
quit(0 if _fails.is_empty() else 1)
return true
## 输入映射检查(真实按键输入无法无头模拟,检查映射配置本身)
func _check_input_maps() -> void:
var fire_ok := false
if InputMap.has_action("fire"):
for event in InputMap.action_get_events("fire"):
if event is InputEventKey and (event as InputEventKey).physical_keycode == 74:
fire_ok = true
if not fire_ok:
_fail("fire action missing J key")
var bomb_ok := false
if InputMap.has_action("bomb"):
for event in InputMap.action_get_events("bomb"):
if event is InputEventKey and (event as InputEventKey).physical_keycode == 75:
bomb_ok = true
if not bomb_ok:
_fail("bomb action missing K key")
func _process(delta: float) -> bool:
_time += delta
if _time > GLOBAL_TIMEOUT:
_fail("global timeout in phase %d" % _phase)
return _finish()
if _game._enemies == null:
return false
_phase_time += delta
match _phase:
0:
_check_input_maps()
if _game.player.bombs != 2:
_fail("initial bombs=%d expected 2" % _game.player.bombs)
# 场上放 3 架敌机 + 2 发敌弹
for i in 3:
var enemy := EnemySmall.new()
enemy.setup(150.0 + 120.0 * i, 300.0 + 60.0 * i, 100.0)
_game._enemies.add_child(enemy)
for i in 2:
var bullet := EnemyBullet.new()
bullet.position = Vector2(120.0 + 200.0 * i, 400.0)
_game._enemy_bullets.add_child(bullet)
_game.player.use_bomb()
_next_phase()
1:
# 首波 spawner 敌机 0.8s 后才出现,检查点在 0.5s 安全
if _phase_time >= 0.5:
var enemies_left := _game._enemies.get_child_count()
var bullets_left := _game._enemy_bullets.get_child_count()
if enemies_left != 0:
_fail("bomb left enemies: %d" % enemies_left)
if bullets_left != 0:
_fail("bomb left enemy bullets: %d" % bullets_left)
if _game.player.bombs != 1:
_fail("bombs=%d expected 1" % _game.player.bombs)
else:
print("[bomb_test] detonate ok: enemies/bullets cleared, bombs 2->1, score=%d" % _game.score)
_next_phase()
2:
_game.player.use_bomb()
_next_phase()
3:
if _phase_time >= 0.3:
if _game.player.bombs != 0:
_fail("second bomb not consumed: %d" % _game.player.bombs)
_game.player.use_bomb() # 空仓
_next_phase()
4:
if _phase_time >= 0.3:
if _game.player.bombs != 0:
_fail("empty stock still fired: %d" % _game.player.bombs)
else:
print("[bomb_test] stock drain + empty guard ok")
var boss := _game.spawn_boss(1.0)
boss.apply_damage(99999)
_next_phase()
5:
if _phase_time >= 1.0:
if _game.player.bombs != 1:
_fail("boss kill did not grant bomb: %d" % _game.player.bombs)
else:
print("[bomb_test] boss kill +1 bomb ok")
# B 道具拾取链路:1 → 2,再补到 5 验证上限
_collect_bomb_pickup()
_next_phase()
6:
if _phase_time >= 0.5:
if _game.player.bombs != 2:
_fail("B pickup did not add bomb: %d" % _game.player.bombs)
else:
print("[bomb_test] B pickup +1 ok")
_collect_bomb_pickup()
_collect_bomb_pickup()
_collect_bomb_pickup()
_collect_bomb_pickup()
_next_phase()
7:
if _phase_time >= 0.5:
if _game.player.bombs != 5:
_fail("bomb cap broken: %d expected 5" % _game.player.bombs)
else:
print("[bomb_test] bomb cap at 5 ok")
return _finish()
return false
func _collect_bomb_pickup() -> void:
var powerups := _game.get_node_or_null("Powerups") as Node2D
var pickup := Powerup.new()
pickup.kind = Powerup.Kind.BOMB
pickup.position = _game.player.global_position
powerups.add_child(pickup)
# 直接触发玩家拾取路径(与 area_entered 信号同一入口)
_game.player._collect_powerup(pickup)