diff --git a/tests/unit/setup.py b/tests/unit/setup.py new file mode 100644 index 00000000..dbd202af --- /dev/null +++ b/tests/unit/setup.py @@ -0,0 +1,98 @@ +""" +Quelques fonctions d'initialisation pour tests unitaires +""" + +from tests.unit import sco_fake_gen +from app import db +from app import models + +from app.scodoc import sco_codes_parcours + + +def build_formation_test(nb_mods=1): + G = sco_fake_gen.ScoFake(verbose=False) + _f = G.create_formation( + acronyme="F3", + titre="Formation 2", + titre_officiel="Titre officiel 2", + type_parcours=sco_codes_parcours.ParcoursBUT.TYPE_PARCOURS, + ) + _ue1 = G.create_ue( + formation_id=_f["formation_id"], acronyme="UE1", titre="ue 1", semestre_idx=2 + ) + _ue2 = G.create_ue( + formation_id=_f["formation_id"], acronyme="UE2", titre="ue 2", semestre_idx=2 + ) + _ue3 = G.create_ue( + formation_id=_f["formation_id"], acronyme="UE3", titre="ue 3", semestre_idx=2 + ) + # une 4eme UE en dehors du semestre 2 + _ = G.create_ue( + formation_id=_f["formation_id"], acronyme="UE41", titre="ue 41", semestre_idx=4 + ) + _mat = G.create_matiere(ue_id=_ue1["ue_id"], titre="matière test") + module_ids = [] + for i in range(nb_mods): + mod = G.create_module( + matiere_id=_mat["matiere_id"], + code=f"TSM{i}", + coefficient=1.0, + titre=f"module test {i}", + ue_id=_ue1["ue_id"], + formation_id=_f["formation_id"], + semestre_id=2, + ) + module_ids.append(mod["id"]) + return G, _f["id"], _ue1["id"], _ue2["id"], _ue3["id"], module_ids + + +def build_modules_with_evaluations( + ue_coefs=(1.0, 2.0, 3.0), nb_mods=1, nb_evals_per_modimpl=1 +): + """Utilisé dans plusieurs tests: + - création formation 3 UE, 1 module + - 1 semestre, nb_mod moduleimpl, 1 eval/moduleimpl + """ + nb_ues = len(ue_coefs) # 3 UEs par défaut dans ce test + G, formation_id, ue1_id, ue2_id, ue3_id, module_ids = build_formation_test( + nb_mods=nb_mods + ) + ue1 = models.UniteEns.query.get(ue1_id) + ue2 = models.UniteEns.query.get(ue2_id) + ue3 = models.UniteEns.query.get(ue3_id) + for module_id in module_ids: + mod = models.Module.query.get(module_id) + # Coef du module vers les UE + c1, c2, c3 = ue_coefs + coefs_mod = {ue1.id: c1, ue2.id: c2, ue3.id: c3} + mod.set_ue_coef_dict(coefs_mod) + assert mod.get_ue_coef_dict() == coefs_mod + # Mise en place: + sem = G.create_formsemestre( + formation_id=formation_id, + semestre_id=2, + date_debut="01/01/2021", + date_fin="30/06/2021", + ) + evaluation_ids = [] + for module_id in module_ids: + mi = G.create_moduleimpl( + module_id=module_id, + formsemestre_id=sem["formsemestre_id"], + ) + moduleimpl_id = mi["id"] + modimpl = models.ModuleImpl.query.get(moduleimpl_id) + assert modimpl.formsemestre.formation.get_parcours().APC_SAE # BUT + # Check ModuleImpl + ues = modimpl.formsemestre.query_ues().all() + assert len(ues) == 3 + # + for _ in range(nb_evals_per_modimpl): + e = G.create_evaluation( + moduleimpl_id=moduleimpl_id, + jour="01/01/2021", + description="evaluation 1", + coefficient=0, + ) + evaluation_ids.append(e["evaluation_id"]) + return G, formation_id, sem, evaluation_ids, ue1, ue2, ue3 diff --git a/tests/unit/test_but_ues.py b/tests/unit/test_but_ues.py new file mode 100644 index 00000000..330cab96 --- /dev/null +++ b/tests/unit/test_but_ues.py @@ -0,0 +1,86 @@ +""" +Test calcul moyennes UE +""" +import numpy as np +import pandas as pd +from tests.unit import setup + +from app.models.etudiants import Identite + +from tests.unit import sco_fake_gen +from app import db +from app import models +from app.comp import moy_mod +from app.comp import moy_ue +from app.comp import inscr_mod +from app.models import Evaluation, formsemestre +from app.scodoc import sco_codes_parcours, sco_saisie_notes +from app.scodoc.sco_utils import NOTES_ATTENTE, NOTES_NEUTRALISE + + +def test_ue_moy(test_client): + """Test calcul moyenne UE avec saisie des notes via ScoDoc""" + ue_coefs = (1.0, 2.0, 3.0) # coefs des modules vers les 3 UE + nb_ues = len(ue_coefs) + nb_mods = 2 # 2 modules + ( + G, + formation_id, + sem, + evaluation_ids, + ue1, + ue2, + ue3, + ) = setup.build_modules_with_evaluations(ue_coefs=ue_coefs, nb_mods=nb_mods) + assert len(evaluation_ids) == nb_mods + formsemestre_id = sem["formsemestre_id"] + formsemestre = models.FormSemestre.query.get(formsemestre_id) + evaluation1 = models.Evaluation.query.get(evaluation_ids[0]) + evaluation2 = models.Evaluation.query.get(evaluation_ids[1]) + etud = G.create_etud(nom="test") + G.inscrit_etudiant(sem, etud) + etudid = etud["etudid"] + # e1 est l'éval du module 1, et e2 l'éval du module 2 + e1p1, e1p2, e1p3 = 1.0, 2.0, 3.0 # poids de l'éval 1 vers les UE 1, 2 et 3 + e2p1, e2p2, e2p3 = 3.0, 1.0, 5.0 # poids de l'éval 2 vers les UE + evaluation1.set_ue_poids_dict({ue1.id: e1p1, ue2.id: e1p2, ue3.id: e1p3}) + evaluation2.set_ue_poids_dict({ue1.id: e2p1, ue2.id: e2p2, ue3.id: e2p3}) + # Les coefs des évaluations: + coef_e1, coef_e2 = 7.0, 11.0 + evaluation1.coefficient = coef_e1 + evaluation2.coefficient = coef_e2 + # Les moduleimpls + modimpls = [evaluation1.moduleimpl, evaluation2.moduleimpl] + # Check inscriptions modules + modimpl_inscr_df = inscr_mod.df_load_modimpl_inscr(formsemestre_id) + assert (modimpl_inscr_df.values == np.array([[1, 1]])).all() + # Coefs des modules vers les UE: + modimpl_coefs_df, ues, modimpls = moy_ue.df_load_modimpl_coefs(formsemestre) + assert modimpl_coefs_df.shape == (nb_ues, nb_mods) + assert len(ues) == nb_ues + assert len(modimpls) == nb_mods + assert (modimpl_coefs_df.values == np.array([ue_coefs] * nb_mods).transpose()).all() + + # --- Change les notes et recalcule les moyennes + # (rappel: on a deux évaluations: evaluation1, evaluation2, et un seul étudiant) + def change_notes(n1, n2): + # Saisie d'une note dans chaque éval + _ = sco_saisie_notes.notes_add(G.default_user, evaluation1.id, [(etudid, n1)]) + _ = sco_saisie_notes.notes_add(G.default_user, evaluation2.id, [(etudid, n2)]) + # Recalcul des moyennes + sem_cube = moy_ue.notes_sem_load_cube(formsemestre_id) + etuds = formsemestre.etuds.all() + etud_moy_ue = moy_ue.compute_ue_moys( + sem_cube, etuds, modimpls, ues, modimpl_inscr_df, modimpl_coefs_df + ) + return etud_moy_ue + + # Cas simple: 1 eval / module, notes normales, + # coefs non nuls. + n1, n2 = 5.0, 13.0 # notes aux 2 evals (1 dans chaque module) + etud_moy_ue = change_notes(5.0, 13.0) + assert etud_moy_ue.shape == (1, nb_ues) # 1 étudiant + assert etud_moy_ue[ue1.id][etudid] == (n1 + n2) / 2 + assert etud_moy_ue[ue2.id][etudid] == (n1 + n2) / 2 + assert etud_moy_ue[ue3.id][etudid] == (n1 + n2) / 2 + #