Files
notytex/backend/tests/unit/test_statistics_service.py
Bertrand Benjamin 2b08eb534a Migration v1 (Flask) -> v2 (FastAPI + Vue.js) complétée
 Changements majeurs:
- Suppression complète du code Flask legacy
- Migration backend FastAPI vers racine /backend
- Migration frontend Vue.js vers racine /frontend
- Suppression de notytex-v2/ (code monté à la racine)

 Validations:
- Backend démarre correctement (port 8000)
- API /api/v2/health répond healthy
- 99/99 tests unitaires passent
- Frontend configuré avec proxy Vite

📝 Documentation:
- README.md réécrit pour v2
- Instructions de démarrage mises à jour
- .gitignore adapté pour backend/frontend/

🎯 Architecture finale:
notytex/
├── backend/     # FastAPI + SQLAlchemy + Pydantic
├── frontend/    # Vue 3 + Vite + TailwindCSS
├── docs/        # Documentation
└── school_management.db  # Base de données (inchangée)

Jalon 6 complété: Application v2 prête pour utilisation!
2025-11-25 21:09:47 +01:00

228 lines
7.3 KiB
Python

"""
Tests unitaires pour le StatisticsService.
"""
import pytest
from domain.services.statistics_service import StatisticsService
class TestStatisticsServiceBasic:
"""Tests basiques pour le service de statistiques."""
def test_calculate_statistics_empty(self):
service = StatisticsService()
result = service.calculate_statistics([])
assert result.count == 0
assert result.mean == 0.0
assert result.median == 0.0
assert result.min == 0.0
assert result.max == 0.0
assert result.std_dev == 0.0
def test_calculate_statistics_single_value(self):
service = StatisticsService()
result = service.calculate_statistics([15.0])
assert result.count == 1
assert result.mean == 15.0
assert result.median == 15.0
assert result.min == 15.0
assert result.max == 15.0
assert result.std_dev == 0.0
def test_calculate_statistics_multiple_values(self):
service = StatisticsService()
scores = [10.0, 12.0, 14.0, 16.0, 18.0]
result = service.calculate_statistics(scores)
assert result.count == 5
assert result.mean == 14.0
assert result.median == 14.0
assert result.min == 10.0
assert result.max == 18.0
# std_dev ≈ 3.16
assert 3.1 < result.std_dev < 3.2
def test_calculate_statistics_even_count(self):
service = StatisticsService()
scores = [10.0, 12.0, 14.0, 16.0]
result = service.calculate_statistics(scores)
assert result.count == 4
assert result.median == 13.0 # (12 + 14) / 2
def test_calculate_statistics_rounding(self):
service = StatisticsService()
scores = [10.333, 12.666, 14.999]
result = service.calculate_statistics(scores)
# Vérifier que les valeurs sont arrondies à 2 décimales
assert result.mean == 12.67
assert result.min == 10.33
assert result.max == 15.0
class TestHistogramCreation:
"""Tests pour la création d'histogrammes."""
def test_create_histogram_empty(self):
service = StatisticsService()
result = service.create_histogram([], 20)
assert len(result.bins) == 0
def test_create_histogram_zero_max(self):
service = StatisticsService()
result = service.create_histogram([5, 10], 0)
assert len(result.bins) == 0
def test_create_histogram_single_value(self):
service = StatisticsService()
result = service.create_histogram([10.0], 20)
assert len(result.bins) == 21
assert result.bins[10].count == 1
assert result.total_count == 1
def test_create_histogram_distribution(self):
service = StatisticsService()
# 5 valeurs: 0-1, 5-6, 10-11, 15-16, 20
scores = [0.5, 5.5, 10.5, 15.5, 20.0]
result = service.create_histogram(scores, 20)
assert result.bins[0].count == 1 # 0-1
assert result.bins[5].count == 1 # 5-6
assert result.bins[10].count == 1 # 10-11
assert result.bins[15].count == 1 # 15-16
assert result.bins[20].count == 1 # 20+
assert result.total_count == 5
def test_create_histogram_max_count(self):
service = StatisticsService()
scores = [10.0, 10.5, 10.8, 5.0] # 3 dans bin 10, 1 dans bin 5
result = service.create_histogram(scores, 20)
assert result.max_count == 3
def test_create_simple_histogram(self):
service = StatisticsService()
scores = [0.5, 5.5, 10.5]
result = service.create_simple_histogram(scores, 20)
assert len(result) == 21
assert result[0] == 1
assert result[5] == 1
assert result[10] == 1
assert sum(result) == 3
class TestPercentileCalculations:
"""Tests pour les calculs de percentiles."""
def test_calculate_percentile_empty(self):
service = StatisticsService()
assert service.calculate_percentile([], 50) == 0.0
def test_calculate_percentile_median(self):
service = StatisticsService()
scores = [1, 2, 3, 4, 5]
assert service.calculate_percentile(scores, 50) == 3.0
def test_calculate_percentile_25(self):
service = StatisticsService()
scores = [1, 2, 3, 4, 5]
# Q1 = 2
assert service.calculate_percentile(scores, 25) == 2.0
def test_calculate_percentile_75(self):
service = StatisticsService()
scores = [1, 2, 3, 4, 5]
# Q3 = 4
assert service.calculate_percentile(scores, 75) == 4.0
def test_calculate_quartiles(self):
service = StatisticsService()
scores = [1, 2, 3, 4, 5, 6, 7, 8, 9]
quartiles = service.calculate_quartiles(scores)
assert quartiles["q1"] == 3.0
assert quartiles["q2"] == 5.0 # Médiane
assert quartiles["q3"] == 7.0
class TestScoreNormalization:
"""Tests pour la normalisation des scores."""
def test_normalize_scores_to_20(self):
service = StatisticsService()
scores = [5, 10, 15] # sur 30
normalized = service.normalize_scores(scores, 30, 20)
assert normalized == [3.33, 6.67, 10.0]
def test_normalize_scores_zero_max(self):
service = StatisticsService()
scores = [5, 10]
normalized = service.normalize_scores(scores, 0, 20)
assert normalized == [0.0, 0.0]
def test_normalize_scores_same_scale(self):
service = StatisticsService()
scores = [10, 15, 20]
normalized = service.normalize_scores(scores, 20, 20)
assert normalized == [10.0, 15.0, 20.0]
def test_normalize_scores_custom_target(self):
service = StatisticsService()
scores = [10, 20] # sur 20
normalized = service.normalize_scores(scores, 20, 100) # vers 100
assert normalized == [50.0, 100.0]
class TestStatisticsResultObject:
"""Tests pour l'objet StatisticsResult."""
def test_to_dict(self):
service = StatisticsService()
result = service.calculate_statistics([10, 15, 20])
result_dict = result.to_dict()
assert "count" in result_dict
assert "mean" in result_dict
assert "median" in result_dict
assert "min" in result_dict
assert "max" in result_dict
assert "std_dev" in result_dict
assert result_dict["count"] == 3
assert result_dict["mean"] == 15.0
assert result_dict["median"] == 15.0
class TestHistogramDataObject:
"""Tests pour l'objet HistogramData."""
def test_to_list(self):
service = StatisticsService()
scores = [5.5, 10.5]
result = service.create_histogram(scores, 20)
counts = result.to_list()
assert isinstance(counts, list)
assert len(counts) == 21
assert sum(counts) == 2
def test_to_dict_list(self):
service = StatisticsService()
scores = [5.5]
result = service.create_histogram(scores, 10)
dict_list = result.to_dict_list()
assert isinstance(dict_list, list)
assert all("range" in d and "count" in d for d in dict_list)