"""StereoYoloConfig 校验与 JSON 加载测试(需求说明 §4:配置外置、fail-fast)。""" import json from pathlib import Path import pytest from stereo_yolo import StereoYoloConfig, load_from_json CONFIG_PATH = Path(__file__).resolve().parents[2] / "config" / "stereo_yolo.json" def _config_dict() -> dict: return json.loads(CONFIG_PATH.read_text(encoding="utf-8")) def _write(tmp_path: Path, data: dict) -> str: path = tmp_path / "stereo_yolo.json" path.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8") return str(path) def test_load_from_json_matches_defaults(): assert load_from_json(str(CONFIG_PATH)) == StereoYoloConfig() def test_whitelist_normalized_to_tuple(): cfg = StereoYoloConfig(class_whitelist=[0, 2]) assert cfg.class_whitelist == (0, 2) def test_missing_field_rejected(tmp_path): data = _config_dict() data.pop("imgsz") with pytest.raises(ValueError, match="缺少配置字段"): load_from_json(_write(tmp_path, data)) def test_unknown_field_rejected(tmp_path): data = _config_dict() data["letterbox_scale"] = 0.5 with pytest.raises(ValueError, match="未知配置字段"): load_from_json(_write(tmp_path, data)) @pytest.mark.parametrize( "field,value", [ ("model_path", 123), ("imgsz", "640"), ("imgsz", True), ("conf_threshold", "0.25"), ("iou_threshold", None), ("class_whitelist", 0), ("class_whitelist", ["0"]), ("device", 5), ("concurrency", 1), ], ) def test_type_error_rejected(tmp_path, field, value): data = _config_dict() data[field] = value with pytest.raises(ValueError, match="配置类型非法"): load_from_json(_write(tmp_path, data)) @pytest.mark.parametrize( "field,value", [ ("model_path", ""), ("imgsz", 0), ("imgsz", 600), ("conf_threshold", -0.1), ("conf_threshold", 1.5), ("iou_threshold", 0.0), ("class_whitelist", []), ("class_whitelist", [-1]), ("device", " "), ("concurrency", "batch"), ], ) def test_invalid_values_rejected(field, value): with pytest.raises(ValueError, match="配置非法"): StereoYoloConfig(**{field: value}) def test_boundary_values_accepted(): cfg = StereoYoloConfig( imgsz=32, conf_threshold=0.0, iou_threshold=1.0, class_whitelist=(0,), device="cpu", concurrency="sequential", ) assert cfg.imgsz == 32