feat: 修复 AI 风险语义并隔离 Mock 数据
This commit is contained in:
@@ -6,7 +6,9 @@ os.environ.setdefault("ALLOWED_STREAM_HOSTS", "localhost,127.0.0.1,100.83.103.1"
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app import main as main_module
|
||||
from app.main import app
|
||||
from app.detector import MockDetector
|
||||
|
||||
# 1x1 透明 PNG
|
||||
TINY_PNG = base64.b64decode(
|
||||
@@ -22,6 +24,8 @@ def test_health():
|
||||
body = r.json()
|
||||
assert body["status"] == "ok"
|
||||
assert body["model"] in ("mock", "onnx")
|
||||
assert body["modelVersion"]
|
||||
assert body["isMock"] is True
|
||||
|
||||
|
||||
def test_detect_ok():
|
||||
@@ -29,6 +33,10 @@ def test_detect_ok():
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body["model"] == "mock"
|
||||
assert body["modelVersion"]
|
||||
assert body["isMock"] is True
|
||||
assert body["status"] == "healthy"
|
||||
assert body["abnormalProbability"] == 0
|
||||
assert len(body["detections"]) >= 1
|
||||
d = body["detections"][0]
|
||||
assert d["class"] in ("healthy", "sick")
|
||||
@@ -36,6 +44,28 @@ def test_detect_ok():
|
||||
assert d["bbox"]["w"] > 0
|
||||
|
||||
|
||||
def test_detect_uses_abnormal_class_confidence(monkeypatch):
|
||||
monkeypatch.setattr(main_module, "detector", MockDetector(class_name="sick", confidence=0.92))
|
||||
r = client.post("/detect", files={"file": ("a.png", TINY_PNG, "image/png")})
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body["status"] == "abnormal"
|
||||
assert body["abnormalProbability"] == 0.92
|
||||
|
||||
|
||||
def test_detect_empty_result_is_unknown(monkeypatch):
|
||||
class EmptyDetector:
|
||||
def detect(self, image_bytes):
|
||||
return []
|
||||
|
||||
monkeypatch.setattr(main_module, "detector", EmptyDetector())
|
||||
r = client.post("/detect", files={"file": ("a.png", TINY_PNG, "image/png")})
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body["status"] == "unknown"
|
||||
assert body["abnormalProbability"] == 0
|
||||
|
||||
|
||||
def test_detect_empty_file_rejected():
|
||||
r = client.post("/detect", files={"file": ("a.png", b"", "image/png")})
|
||||
assert r.status_code == 400
|
||||
|
||||
@@ -2,7 +2,7 @@ import base64
|
||||
|
||||
import pytest
|
||||
|
||||
from app.detector import MockDetector
|
||||
from app.detector import MockDetector, abnormal_probability, detection_status
|
||||
|
||||
# 1x1 透明 PNG
|
||||
TINY_PNG = base64.b64decode(
|
||||
@@ -23,3 +23,22 @@ def test_mock_detector_rejects_invalid_image():
|
||||
det = MockDetector()
|
||||
with pytest.raises(ValueError):
|
||||
det.detect(b"not an image")
|
||||
|
||||
|
||||
def test_abnormal_probability_ignores_healthy_and_unknown():
|
||||
detections = [
|
||||
{"class_name": "healthy", "confidence": 0.95},
|
||||
{"class_name": "unknown", "confidence": 0.8},
|
||||
{"class_name": "sick", "confidence": 0.72},
|
||||
]
|
||||
assert abnormal_probability(detections, ("healthy", "sick")) == 0.72
|
||||
|
||||
|
||||
def test_detection_status_returns_unknown_for_empty_or_unknown():
|
||||
assert detection_status([], ("healthy", "sick")) == "unknown"
|
||||
assert detection_status([{"class_name": "unknown", "confidence": 0.8}], ("healthy", "sick")) == "unknown"
|
||||
assert detection_status([{"class_name": "healthy", "confidence": 0.95}], ("healthy", "sick")) == "healthy"
|
||||
assert detection_status(
|
||||
[{"class_name": "white_muscardine", "confidence": 0.7}],
|
||||
("healthy", "white_muscardine", "nuclear_polyhedrosis"),
|
||||
) == "abnormal"
|
||||
|
||||
Reference in New Issue
Block a user