-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_feedback.py
More file actions
210 lines (176 loc) · 7.48 KB
/
Copy pathtest_feedback.py
File metadata and controls
210 lines (176 loc) · 7.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
"""tests.test_feedback — 交互式反馈回路测试"""
import json
import pytest
from lab_analysis.feedback import (
clear_feedback,
get_confidence_adjustments,
load_feedback,
record_correction,
)
@pytest.fixture
def mock_feedback_path(tmp_path, monkeypatch):
"""临时改 WORK_ROOT 避免写入真实 data/"""
import lab_analysis.feedback as fb
original_root = fb.WORK_ROOT
fb.WORK_ROOT = tmp_path
yield tmp_path
fb.WORK_ROOT = original_root
class TestLoadFeedback:
def test_no_file_returns_empty_template(self, mock_feedback_path):
fb = load_feedback("test_deid")
assert fb["patient_id"] == "test_deid"
assert fb["corrections"] == []
assert fb["confidence_adjustments"] == {}
def test_existing_file_loaded(self, mock_feedback_path):
path = mock_feedback_path / "data" / "test_deid" / "feedback.json"
path.parent.mkdir(parents=True)
path.write_text(json.dumps({"patient_id": "test_deid", "corrections": [{"test": 1}]}))
fb = load_feedback("test_deid")
assert len(fb["corrections"]) == 1
class TestRecordCorrection:
def test_adds_correction(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="急性胰腺炎",
original_confidence=0.82,
corrected_confidence=0.90,
user_comment="临床确诊",
)
assert len(fb["corrections"]) == 1
c = fb["corrections"][0]
assert c["original_hypothesis"] == "慢性胰腺炎(活动期)"
assert c["corrected_hypothesis"] == "急性胰腺炎"
assert "corrected_at" in c
def test_confidence_adjustment_updated(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="急性胰腺炎",
original_confidence=0.82,
corrected_confidence=0.90,
)
adj = fb.get("confidence_adjustments", {})
assert "chronic_pancreatitis_active" in adj
# confidence diff = 0.08, not > 0.1, but hypothesis changed → -0.10
assert adj["chronic_pancreatitis_active"] <= 0
class TestGetConfidenceAdjustments:
def test_returns_adjustments(self, mock_feedback_path):
# First record something
record_correction("test_deid", "hyp A", "hyp B", 0.9, 0.5)
adj = get_confidence_adjustments("test_deid")
assert isinstance(adj, dict)
def test_no_feedback_returns_empty(self, mock_feedback_path):
adj = get_confidence_adjustments("no_data")
assert adj == {}
class TestClearFeedback:
def test_clears_existing(self, mock_feedback_path):
record_correction("test_deid", "a", "b", 0.8, 0.9)
assert (mock_feedback_path / "data" / "test_deid" / "feedback.json").exists()
clear_feedback("test_deid")
assert not (mock_feedback_path / "data" / "test_deid" / "feedback.json").exists()
def test_clear_nonexistent_is_noop(self, mock_feedback_path, caplog):
import logging
caplog.set_level(logging.INFO)
clear_feedback("never_recorded")
text = " ".join(rec.getMessage() for rec in caplog.records)
assert "无反馈记录" in text
class TestRecordCorrectionBranches:
"""覆盖 _auto_adjust_confidence 的各分支"""
def test_corrected_confidence_none_falls_back(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="急性腕腺炎",
original_confidence=0.5,
corrected_confidence=None,
)
c = fb["corrections"][0]
# corrected_confidence=None 时 fallback 到 original_confidence
assert c["corrected_confidence"] == 0.5
def test_unknown_hypothesis_no_adjustment(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="一个完全未知的假设",
corrected_hypothesis="另一个假设",
original_confidence=0.8,
corrected_confidence=0.8,
)
assert fb.get("confidence_adjustments", {}) == {}
def test_confidence_increase_above_threshold(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="慢性胰腺炎(活动期)",
original_confidence=0.5,
corrected_confidence=0.8, # +0.3 > 0.1
)
adj = fb["confidence_adjustments"]
assert adj["chronic_pancreatitis_active"] >= 0.05
def test_confidence_decrease_below_threshold(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="慢性胰腺炎(活动期)",
original_confidence=0.8,
corrected_confidence=0.5, # -0.3 < -0.1
)
adj = fb["confidence_adjustments"]
assert adj["chronic_pancreatitis_active"] <= -0.05
def test_user_comment_default_empty(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="a",
corrected_hypothesis="b",
)
assert fb["corrections"][0]["user_comment"] == ""
def test_run_timestamp_defaults_to_now(self, mock_feedback_path):
fb = record_correction(
"test_deid",
original_hypothesis="a",
corrected_hypothesis="b",
)
# 14位数字串 YYYYMMDD_HHMMSS
assert "_" in fb["corrections"][0]["run_timestamp"]
class TestPrintFeedback:
def test_empty_corrections(self, mock_feedback_path, caplog):
import logging
from lab_analysis.feedback import load_feedback, print_feedback
caplog.set_level(logging.INFO)
print_feedback(load_feedback("empty_deid"))
text = " ".join(rec.getMessage() for rec in caplog.records)
assert "无纠正记录" in text
def test_with_corrections_and_adjustments(self, mock_feedback_path, caplog):
import logging
from lab_analysis.feedback import print_feedback
caplog.set_level(logging.INFO)
record_correction(
"test_deid",
original_hypothesis="慢性胰腺炎(活动期)",
corrected_hypothesis="急性腕腺炎",
original_confidence=0.8,
corrected_confidence=0.5,
user_comment="确诊",
)
print_feedback(
{
"patient_id": "test_deid",
"generated": "2026-06-21T10:00:00",
"corrections": [
{
"run_timestamp": "20260621_100000",
"original_hypothesis": "A",
"original_confidence": 0.8,
"corrected_hypothesis": "B",
"corrected_confidence": 0.5,
"user_comment": "备注",
}
],
"confidence_adjustments": {"chronic_pancreatitis_active": -0.15},
}
)
text = " ".join(rec.getMessage() for rec in caplog.records)
assert "原假设: A" in text
assert "纠正为: B" in text
assert "备注" in text
assert "chronic_pancreatitis_active" in text