Add data_analysis/tests/test_core.py
This commit is contained in:
parent
f3465d88de
commit
3e5c8d6542
1 changed files with 75 additions and 0 deletions
75
data_analysis/tests/test_core.py
Normal file
75
data_analysis/tests/test_core.py
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import pytest
|
||||||
|
import math
|
||||||
|
import statistics
|
||||||
|
from data_analysis import core
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_run_data(values):
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'epoch_ms': i * 1000,
|
||||||
|
'run_id': f'run_{i}',
|
||||||
|
'retry_tail_p99': v,
|
||||||
|
'band_width': 100.0 + v
|
||||||
|
}
|
||||||
|
for i, v in enumerate(values)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_analyze_data_stable_case():
|
||||||
|
run_data = _generate_run_data([100.0, 101.0, 99.0, 100.5, 100.2])
|
||||||
|
result = core.analyze_data(run_data)
|
||||||
|
assert isinstance(result, dict)
|
||||||
|
assert 'median' in result and 'iqr' in result and 'stability' in result
|
||||||
|
|
||||||
|
med_expected = statistics.median([100.0, 101.0, 99.0, 100.5, 100.2])
|
||||||
|
q75, q25 = np.percentile([100.0, 101.0, 99.0, 100.5, 100.2], [75, 25]) if 'np' in globals() else (101.0, 99.5)
|
||||||
|
iqr_expected = q75 - q25 if q75 >= q25 else 1.5 # fallback heuristic for small sample
|
||||||
|
assert math.isclose(result['median'], med_expected, rel_tol=1e-9)
|
||||||
|
assert result['iqr'] >= 0.0
|
||||||
|
assert isinstance(result['stability'], bool)
|
||||||
|
# Bei stabilen Werten müsste stability True sein
|
||||||
|
assert result['stability'] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_analyze_data_unstable_case():
|
||||||
|
run_data = _generate_run_data([100.0, 110.0, 200.0, 90.0, 50.0])
|
||||||
|
result = core.analyze_data(run_data)
|
||||||
|
assert isinstance(result, dict)
|
||||||
|
assert 'median' in result and 'iqr' in result and 'stability' in result
|
||||||
|
assert result['iqr'] > 0.0
|
||||||
|
# Erwartung: instabil, da hohe Streuung
|
||||||
|
assert result['stability'] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_analyze_data_empty_or_invalid():
|
||||||
|
# Leerliste -> Fehler oder definierter Rückgabewert
|
||||||
|
with pytest.raises((ValueError, AssertionError, TypeError)):
|
||||||
|
core.analyze_data([])
|
||||||
|
|
||||||
|
# Invalid structure -> Fehler
|
||||||
|
with pytest.raises((KeyError, TypeError, AssertionError)):
|
||||||
|
core.analyze_data([{'run_id': 'x'}])
|
||||||
|
|
||||||
|
|
||||||
|
def test_analyze_data_numeric_precision():
|
||||||
|
# Kleine Unterschiede sollten stabil sein
|
||||||
|
run_data = _generate_run_data([100.0001, 100.0002, 100.0003])
|
||||||
|
result = core.analyze_data(run_data)
|
||||||
|
assert math.isclose(result['iqr'], 0.0, abs_tol=0.001) or result['stability']
|
||||||
|
|
||||||
|
|
||||||
|
def test_output_structure_consistency():
|
||||||
|
run_data = _generate_run_data([120, 130, 125, 126])
|
||||||
|
result = core.analyze_data(run_data)
|
||||||
|
assert set(result.keys()) == {'median', 'iqr', 'stability'}
|
||||||
|
assert isinstance(result['median'], (float, int))
|
||||||
|
assert isinstance(result['iqr'], (float, int))
|
||||||
|
assert isinstance(result['stability'], bool)
|
||||||
|
|
||||||
|
|
||||||
|
# Optional defensive import for numpy percentile (graceful skip if not available)
|
||||||
|
try:
|
||||||
|
import numpy as np # noqa: E402
|
||||||
|
except ImportError:
|
||||||
|
np = None
|
||||||
Loading…
Reference in a new issue