from __future__ import annotations from app.ml.evaluation import Evaluator, EvalReport, Metric from app.ml.feature_store import FeatureStore, FeatureVector from app.ml.training import TrainingPipeline def _vector(sensor_id: str, temperature: float, label: str | None = None) -> FeatureVector: return FeatureVector(sensor_id=sensor_id, values={"temperature": temperature}, label=label) def test_end_to_end_training_then_evaluation() -> None: store = FeatureStore() store.add_batch([_vector("sensor.kitchen", 19.0), _vector("sensor.bedroom", 18.5)]) pipeline = TrainingPipeline(store) artifact = pipeline.run("artifact_v1") evaluator = Evaluator(pipeline) predictions = [ "artifact_v1:sensor.kitchen:{'temperature': 21.0}", "artifact_v1:sensor.bedroom:{'temperature': 18.5}", ] report = evaluator.evaluate(artifact.artifact_id, predictions) assert isinstance(report, EvalReport) assert report.sample_size == len(predictions) assert any(metric.name == "coverage" for metric in report.metrics) def test_metric_helpers_are_serializable() -> None: metric = Metric(name="coverage", value=0.85, threshold=0.8) assert metric.name == "coverage" assert metric.value == 0.85 assert metric.threshold == 0.8