shopstack / tests /test_bench_regression.py
pranaysuyash's picture
Sync ShopStack 2026-06-15: corrections panel, empty-state rewrite, market-source suppression
8294cde verified
Raw
History Blame Contribute Delete
6.2 kB
"""EVAL-1: Benchmark results recording + regression detection tests.
Verifies the ``shopstack.eval.bench_results`` infrastructure that converts
accuracy claims from prose into CI-assertable quality gates. This test
exercises:
1. Saving and loading benchmark results (JSONL round-trip).
2. Loading the committed baseline.
3. Regression detection for "higher is better" metrics (accuracy, iou).
4. Regression detection for "lower is better" metrics (wer, latency).
5. The baseline file itself is valid and covers key capabilities.
"""
from __future__ import annotations
import json
from pathlib import Path
import pytest
from shopstack.eval.bench_results import (
BASELINE_PATH,
BenchmarkResult,
check_regression,
load_baseline,
save_result,
)
class TestBenchmarkResultSchema:
def test_result_is_frozen_and_serializable(self):
r = BenchmarkResult(
model="test-model",
capability="test_cap",
metric="accuracy",
value=0.95,
sample_size=100,
evidence="tests/test_bench_regression.py",
)
assert r.value == 0.95
# Frozen dataclass β€” mutation should fail
with pytest.raises(AttributeError):
r.value = 0.50 # type: ignore[misc]
# Serializable to dict
d = r.__dict__ if hasattr(r, "__dict__") else json.loads(json.dumps(r.__dataclass_fields__)) # noqa
assert d is not None
class TestSaveLoadRoundTrip:
def test_save_and_read_result(self, tmp_path):
"""save_result appends to JSONL; the line parses back to the fields."""
results_file = tmp_path / "results.jsonl"
r = BenchmarkResult(
model="ministral-8b",
capability="planner_tool_calling",
metric="accuracy",
value=0.92,
sample_size=10,
evidence="bench.py",
)
save_result(r, path=results_file)
assert results_file.exists()
line = results_file.read_text(encoding="utf-8").strip()
parsed = json.loads(line)
assert parsed["model"] == "ministral-8b"
assert parsed["value"] == 0.92
assert parsed["capability"] == "planner_tool_calling"
def test_multiple_results_append(self, tmp_path):
"""Each save appends a new line β€” results accumulate."""
results_file = tmp_path / "results.jsonl"
for v in (0.90, 0.92, 0.95):
save_result(
BenchmarkResult("m", "cap", "accuracy", v, evidence="b"),
path=results_file,
)
lines = results_file.read_text(encoding="utf-8").strip().split("\n")
assert len(lines) == 3
class TestBaselineIntegrity:
def test_baseline_file_exists(self):
"""The committed baseline must exist β€” it's the known-good reference."""
assert BASELINE_PATH.exists(), (
f"Benchmark baseline not found at {BASELINE_PATH}. "
"This file is git-tracked and defines the known-good accuracy values."
)
def test_baseline_loads_and_has_capabilities(self):
baseline = load_baseline()
assert isinstance(baseline, dict)
assert len(baseline) > 0, "Baseline must define at least one capability"
def test_baseline_covers_planner(self):
"""The planner tool-calling accuracy must be in the baseline β€” it's
the product's most critical AI quality metric."""
baseline = load_baseline()
assert "planner_tool_calling" in baseline
assert "accuracy" in baseline["planner_tool_calling"]
assert 0.0 <= baseline["planner_tool_calling"]["accuracy"] <= 1.0
def test_baseline_covers_known_failures(self):
"""Known limitations (Hindi OCR 0%) must be recorded in the baseline
so they're not silently re-claimed."""
baseline = load_baseline()
assert "ocr_devanagari" in baseline
assert baseline["ocr_devanagari"]["accuracy"] < 0.20
class TestRegressionDetection:
def test_higher_is_better_no_regression(self):
"""Accuracy at or above baseline-tolerance passes."""
baseline_entry = {"accuracy": 0.90}
measured = BenchmarkResult("m", "cap", "accuracy", 0.88, evidence="t")
report = check_regression(baseline_entry, measured, tolerance=0.10)
# 0.88 >= 0.90 * 0.90 = 0.81 β†’ pass
assert report.passed is True
def test_higher_is_better_regression_detected(self):
"""Accuracy dropping more than tolerance triggers a regression."""
baseline_entry = {"accuracy": 0.90}
measured = BenchmarkResult("m", "cap", "accuracy", 0.70, evidence="t")
report = check_regression(baseline_entry, measured, tolerance=0.10)
# 0.70 < 0.81 β†’ regression
assert report.passed is False
assert "REGRESSION" in report.summary
def test_lower_is_better_no_regression(self):
"""WER at or below baseline-tolerance passes."""
baseline_entry = {"wer": 0.25}
measured = BenchmarkResult("m", "cap", "wer", 0.27, evidence="t")
report = check_regression(baseline_entry, measured, tolerance=0.10)
# 0.27 <= 0.25 * 1.10 = 0.275 β†’ pass
assert report.passed is True
def test_lower_is_better_regression_detected(self):
"""WER increasing beyond tolerance triggers a regression."""
baseline_entry = {"wer": 0.25}
measured = BenchmarkResult("m", "cap", "wer", 0.40, evidence="t")
report = check_regression(baseline_entry, measured, tolerance=0.10)
# 0.40 > 0.275 β†’ regression
assert report.passed is False
assert "REGRESSION" in report.summary
def test_report_summary_is_human_readable(self):
"""The summary must contain enough context to diagnose without code."""
baseline_entry = {"accuracy": 0.90}
measured = BenchmarkResult("ministral-8b", "planner", "accuracy", 0.85, evidence="bench.py")
report = check_regression(baseline_entry, measured, tolerance=0.10)
assert "planner" in report.summary
assert "ministral-8b" in report.summary
assert "bench.py" in report.summary
assert "0.85" in report.summary