"""Tests for the offline baseline comparison script.""" import pytest from scripts.compare_baselines import run_comparison ONLINE_KEY = "Mahalanobis + ADWIN (online)" def test_comparison_returns_three_methods(): """run_comparison returns results for all three methods.""" results = run_comparison(seed=42, verbose=False) assert "Z-Score (max |z|>2.5)" in results assert "Isolation Forest (batch)" in results assert ONLINE_KEY in results def test_all_metrics_in_valid_range(): """All returned metrics are floats in [0, 1] (or nan for AUC edge cases).""" results = run_comparison(seed=42, verbose=False) for name, m in results.items(): for key in ("precision", "recall", "f1"): assert 0.0 <= m[key] <= 1.0, f"{name} {key}={m[key]} out of range" if m["roc_auc"] == m["roc_auc"]: # skip NaN assert 0.0 <= m["roc_auc"] <= 1.0, f"{name} roc_auc={m['roc_auc']} out of range" def test_online_method_has_latency(): """The online method reports mean per-observation latency in microseconds.""" results = run_comparison(seed=42, verbose=False) online = results[ONLINE_KEY] assert "mean_latency_us" in online assert online["mean_latency_us"] > 0 def test_mahalanobis_beats_zscore_on_f1(): """Mahalanobis + ADWIN should outperform Z-Score on F1 (catches contextual anomalies).""" results = run_comparison(seed=42, verbose=False) online_f1 = results[ONLINE_KEY]["f1"] zscore_f1 = results["Z-Score (max |z|>2.5)"]["f1"] assert online_f1 > zscore_f1, ( f"Mahalanobis F1={online_f1:.3f} should exceed Z-Score F1={zscore_f1:.3f}" ) def test_results_are_reproducible(): """Two runs with the same seed produce identical results.""" r1 = run_comparison(seed=42, verbose=False) r2 = run_comparison(seed=42, verbose=False) for name in r1: for key in ("precision", "recall", "f1"): assert r1[name][key] == r2[name][key], f"{name} {key} not reproducible"