feat: BIO_NORMALS 33 analytes + interprétations cliniques + cohérence DAS/bio étendue
- BIO_NORMALS passe de 13 à 33 tests (cardio, infectio, métabo, thyroïde, hémato, hépatique) - _BIO_INTERPRETATION synchronisé (33 entrées, 3 clés high/low/normal chacune) - _DAS_BIO_CHECKS étendu de 13 à 38 patterns (sepsis, infarctus, EP, diabète, thyroïde, etc.) - lab_value_sanity.yaml étendu avec 20 garde-fous plausibilité nouveaux tests - tests/test_bio_normals.py : 32 tests (complétude, concordance, _is_abnormal) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
134
tests/test_bio_normals.py
Normal file
134
tests/test_bio_normals.py
Normal file
@@ -0,0 +1,134 @@
|
||||
"""Tests unitaires pour les plages de référence biologiques."""
|
||||
|
||||
import pytest
|
||||
|
||||
from src.medical.bio_normals import BIO_NORMALS, _is_abnormal
|
||||
from src.control.cpam_context import _BIO_INTERPRETATION
|
||||
|
||||
|
||||
class TestBioNormalsCompleteness:
|
||||
"""Vérifie la complétude et la cohérence de BIO_NORMALS."""
|
||||
|
||||
def test_has_33_analytes(self):
|
||||
assert len(BIO_NORMALS) == 33
|
||||
|
||||
def test_all_tuples_are_valid(self):
|
||||
for name, (lo, hi) in BIO_NORMALS.items():
|
||||
assert isinstance(lo, (int, float)), f"{name}: lo doit être numérique"
|
||||
assert isinstance(hi, (int, float)), f"{name}: hi doit être numérique"
|
||||
assert lo <= hi, f"{name}: lo ({lo}) > hi ({hi})"
|
||||
|
||||
def test_known_analytes_present(self):
|
||||
expected = {
|
||||
"CRP", "Hémoglobine", "Plaquettes", "Leucocytes", "Créatinine",
|
||||
"Sodium", "Potassium", "ASAT", "ALAT", "GGT", "PAL",
|
||||
"Bilirubine totale", "Lipasémie",
|
||||
# Nouveaux Phase 5
|
||||
"Troponine", "BNP", "NT-proBNP", "D-dimères", "INR", "Fibrinogène",
|
||||
"Procalcitonine", "Lactate", "Glycémie", "HbA1c", "Albumine",
|
||||
"Urée", "Acide urique", "TP", "TCA", "Ferritine", "LDH",
|
||||
"Bilirubine directe", "TSH", "VS",
|
||||
}
|
||||
assert set(BIO_NORMALS.keys()) == expected
|
||||
|
||||
|
||||
class TestBioInterpretationConcordance:
|
||||
"""Vérifie que BIO_NORMALS et _BIO_INTERPRETATION sont synchronisés."""
|
||||
|
||||
def test_every_normal_has_interpretation(self):
|
||||
missing = set(BIO_NORMALS) - set(_BIO_INTERPRETATION)
|
||||
assert not missing, f"BIO_NORMALS sans interprétation: {missing}"
|
||||
|
||||
def test_every_interpretation_has_normal(self):
|
||||
extra = set(_BIO_INTERPRETATION) - set(BIO_NORMALS)
|
||||
assert not extra, f"Interprétation sans BIO_NORMALS: {extra}"
|
||||
|
||||
def test_all_interpretations_have_three_keys(self):
|
||||
for name, interp in _BIO_INTERPRETATION.items():
|
||||
assert "high" in interp, f"{name}: manque 'high'"
|
||||
assert "low" in interp, f"{name}: manque 'low'"
|
||||
assert "normal" in interp, f"{name}: manque 'normal'"
|
||||
|
||||
|
||||
class TestIsAbnormal:
|
||||
"""Tests pour _is_abnormal() sur les nouveaux et anciens analytes."""
|
||||
|
||||
def test_crp_high(self):
|
||||
assert _is_abnormal("CRP", "180") is True
|
||||
|
||||
def test_crp_normal(self):
|
||||
assert _is_abnormal("CRP", "3") is False
|
||||
|
||||
def test_hemoglobine_low(self):
|
||||
assert _is_abnormal("Hémoglobine", "8.5") is True
|
||||
|
||||
def test_hemoglobine_normal(self):
|
||||
assert _is_abnormal("Hémoglobine", "14.5") is False
|
||||
|
||||
# Nouveaux analytes
|
||||
def test_troponine_high(self):
|
||||
assert _is_abnormal("Troponine", "0.15") is True
|
||||
|
||||
def test_troponine_normal(self):
|
||||
assert _is_abnormal("Troponine", "0.02") is False
|
||||
|
||||
def test_bnp_high(self):
|
||||
assert _is_abnormal("BNP", "500") is True
|
||||
|
||||
def test_bnp_normal(self):
|
||||
assert _is_abnormal("BNP", "50") is False
|
||||
|
||||
def test_lactate_high(self):
|
||||
assert _is_abnormal("Lactate", "4.5") is True
|
||||
|
||||
def test_lactate_normal(self):
|
||||
assert _is_abnormal("Lactate", "1.2") is False
|
||||
|
||||
def test_glycemie_high(self):
|
||||
assert _is_abnormal("Glycémie", "8.0") is True
|
||||
|
||||
def test_glycemie_low(self):
|
||||
assert _is_abnormal("Glycémie", "2.5") is True
|
||||
|
||||
def test_glycemie_normal(self):
|
||||
assert _is_abnormal("Glycémie", "4.5") is False
|
||||
|
||||
def test_tsh_high(self):
|
||||
assert _is_abnormal("TSH", "10.0") is True
|
||||
|
||||
def test_tsh_low(self):
|
||||
assert _is_abnormal("TSH", "0.1") is True
|
||||
|
||||
def test_tsh_normal(self):
|
||||
assert _is_abnormal("TSH", "2.5") is False
|
||||
|
||||
def test_inr_high(self):
|
||||
assert _is_abnormal("INR", "3.5") is True
|
||||
|
||||
def test_inr_normal(self):
|
||||
assert _is_abnormal("INR", "1.0") is False
|
||||
|
||||
def test_albumine_low(self):
|
||||
assert _is_abnormal("Albumine", "20") is True
|
||||
|
||||
def test_albumine_normal(self):
|
||||
assert _is_abnormal("Albumine", "42") is False
|
||||
|
||||
def test_ferritine_low(self):
|
||||
assert _is_abnormal("Ferritine", "5") is True
|
||||
|
||||
def test_ferritine_normal(self):
|
||||
assert _is_abnormal("Ferritine", "150") is False
|
||||
|
||||
# Valeurs textuelles
|
||||
def test_text_negative(self):
|
||||
assert _is_abnormal("CRP", "négative") is False
|
||||
|
||||
def test_text_positive(self):
|
||||
assert _is_abnormal("CRP", "positive") is True
|
||||
|
||||
def test_unknown_test(self):
|
||||
assert _is_abnormal("TestInconnu", "42") is None
|
||||
|
||||
def test_unparseable_value(self):
|
||||
assert _is_abnormal("CRP", "non dosé") is None
|
||||
Reference in New Issue
Block a user