interview / tests /test_03_randomness.py
Lee93whut
feat(env): Gymnasium maze env, 3-channel obs, BFS reachability
fe0625d
"""
测试模块 03 —— 随机性与可复现性
需求覆盖
--------
* R1:seed 参数控制可复现性
* RF1:BFS 连通性保证(起终点强制可达)
对应用例
--------
TC-08, TC-09, TC-10
"""
from __future__ import annotations
import numpy as np
import pytest
from maze_env import MazeEnv
class TestRandomness:
"""验证 BFS 连通性、seed 可复现性及不同 seed 产生不同地图。"""
# ------------------------------------------------------------------ #
# TC-08 BFS 连通性压力测试 #
# ------------------------------------------------------------------ #
@pytest.mark.slow
def test_bfs_connectivity_pressure(self, env_dense: MazeEnv) -> None:
"""TC-08:高密度障碍下,连续 50 次 reset 均保证起终点可达。
输入: MazeEnv(grid_size=10, obstacle_density=0.45),reset() × 50
期望: 每次 reset 后,obs[1](agent)与 obs[2](goal)均有唯一激活格,
且地图合法(不抛出异常,obs shape 正确)
实测: 检查 obs shape 及通道 sum
"""
for i in range(50):
obs, info = env_dense.reset()
assert obs.shape == (4, 10, 10), f"第 {i} 次 reset shape 错误"
assert float(obs[1].sum()) == 1.0, f"第 {i} 次 reset agent 通道异常"
assert float(obs[2].sum()) == 1.0, f"第 {i} 次 reset goal 通道异常"
# ------------------------------------------------------------------ #
# TC-09 相同 seed 可复现 #
# ------------------------------------------------------------------ #
@pytest.mark.unit
def test_same_seed_reproducible(self) -> None:
"""TC-09:相同 seed 两次 reset,产生完全相同的地图与 obs。
输入: 两个独立实例均使用 seed=42,各调用 reset()
期望: obs1 与 obs2 逐元素相等(np.array_equal)
实测: np.array_equal(obs1, obs2)
"""
env_a = MazeEnv(grid_size=8, obstacle_density=0.3, seed=42)
env_b = MazeEnv(grid_size=8, obstacle_density=0.3, seed=42)
obs_a, _ = env_a.reset()
obs_b, _ = env_b.reset()
assert np.array_equal(obs_a, obs_b), "相同 seed 产生的地图应完全一致"
@pytest.mark.unit
def test_same_seed_reset_twice_reproducible(self) -> None:
"""TC-09b:同一实例用相同 seed 调用两次 reset(),结果相同。
输入: env.reset(seed=5),env.reset(seed=5)
期望: 两次 obs 完全相等
实测: np.array_equal
"""
env = MazeEnv(grid_size=6, obstacle_density=0.2)
obs_first, _ = env.reset(seed=5)
obs_second, _ = env.reset(seed=5)
assert np.array_equal(obs_first, obs_second), \
"同一实例以相同 seed 重置,结果应可复现"
# ------------------------------------------------------------------ #
# TC-10 不同 seed 产生不同地图 #
# ------------------------------------------------------------------ #
@pytest.mark.unit
def test_different_seeds_different_maps(self) -> None:
"""TC-10:不同 seed 应产生不同的 wall_map(obs[0])。
输入: seed=0 与 seed=1,obstacle_density=0.3,grid_size=10
期望: obs_0[0] != obs_1[0](至少有一个元素不同)
实测: not np.array_equal(obs_0[0], obs_1[0])
"""
env_0 = MazeEnv(grid_size=10, obstacle_density=0.3, seed=0)
env_1 = MazeEnv(grid_size=10, obstacle_density=0.3, seed=1)
obs_0, _ = env_0.reset()
obs_1, _ = env_1.reset()
assert not np.array_equal(obs_0[0], obs_1[0]), \
"不同 seed 应产生不同的墙壁地图"