anomaly-detection / tests /test_baselines.py
zeetay's picture
initial deploy
b0add2b verified
Raw
History Blame Contribute Delete
2 kB
"""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"