| """ |
| 测试模块 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 产生不同地图。""" |
|
|
| |
| |
| |
|
|
| @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 通道异常" |
|
|
| |
| |
| |
|
|
| @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 重置,结果应可复现" |
|
|
| |
| |
| |
|
|
| @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 应产生不同的墙壁地图" |
|
|