Historique des versions

Version Date Rédacteur Description

1.0.0

18/06/2026

Équipe Technique

Version initiale

1.1.0

11/10/2026

Équipe Technique

Mise à jour d’ensemble. Les cas d’utilisation, les règles de gestion et les scénarios de recette sont alignés sur le comportement attendu de la solution. Les schémas de données, les vues d’exécution et les diagrammes de séquence sont repris sur le modèle et les échanges livrés. Le dictionnaire des données est ramené aux tables structurantes, le modèle complet étant porté en annexe. Les documents sont mis en cohérence entre eux sur les statuts, les rôles, les interfaces et les nomenclatures.

Diffusion

Destinataires Pour validation Pour information

COPIL

X

Validation

Représentants Valideur Date

DCE

MND

ASIN

MESRS - DSI

UNIVERSITÉS - DSI

DSI Présidence

1. Introduction

1.1. Objectif

Ce document décrit la stratégie, l’approche et l’organisation des tests unitaires pour l’ensemble des composantes logicielles de la plateforme BDES. Il définit :

  • Les composantes logicielles couvertes par les tests unitaires

  • Les technologies et outils de test utilisés par composante

  • L’approche de test (patterns, conventions, anti-patterns)

  • Les critères de réussite et seuils de couverture

  • Les environnements d’exécution des tests

1.2. Périmètre

Le plan couvre les tests unitaires des 8 composantes logicielles livrables de la plateforme BDES. Les tests unitaires vérifient le comportement de chaque unité de code (classe, fonction, composant) de manière isolée, avec ses dépendances simulées (mockées).

Sont hors périmètre de ce document :

  • Les tests d’intégration

  • Les tests end-to-end / recette fonctionnelle

  • Les tests de performance et de charge

1.3. Glossaire

Terme Définition

Test unitaire

Test vérifiant le comportement d’une unité de code isolée (classe, méthode, composant Vue)

Mock

Objet simulé remplaçant une dépendance réelle pour isoler l’unité testée

Couverture de code

Pourcentage de lignes ou branches de code exécutées lors des tests

Pattern AAA

Arrange / Act / Assert - structure en 3 phases d’un test unitaire

JaCoCo

Java Code Coverage - outil de mesure de la couverture du code Java

Testcontainers

Bibliothèque Java fournissant des conteneurs Docker éphémères pour les tests d’intégration

2. Composantes logicielles de la solution

2.1. Composantes couvertes par le plan de test unitaire

# Composante Technologie Description

1

API Évaluation

Java 17, Spring Boot 3.4.6

Gère le cycle de vie complet des évaluations : création et activation des campagnes, soumission et suivi des dossiers enseignants, affectation aux commissions d’évaluation, processus de notation et validation.

2

API Référentiel

Java 17, Spring Boot 3.4.6

Consolide et normalise les données de référence de l’enseignement supérieur depuis plusieurs sources (universités, ministère), puis les expose via API REST et X-ROAD.

3

API Notifications

Java 17, Spring Boot 3.4.6

Envoie les notifications par email et WebSocket, gère les templates personnalisables et la logique de retry sur événements système.

4

Bibliothèques partagées

Java 17

Fournit les composants transversaux partagés entre les microservices : modèle de données, mapping, sécurité, cache, clients inter-services.

5

API Utilisateurs

Java 17, Spring Boot 3.4.6

Réconcilie les identités utilisateur depuis Keycloak et synchronise les données avec la base BDES.

6

Event Listener Keycloak

Java 17, Keycloak SPI

Extension Keycloak qui propage les événements utilisateur (création, modification, suppression) vers l’API Utilisateurs via webhooks.

7

Frontend

Nuxt 3, Vue 3, TypeScript

Interface web pour les enseignants, évaluateurs et administrateurs DCE : soumission de dossiers, évaluation, validation des résultats.

8

bdes-migration

Python 3.9+

Scripts de migration one-shot des données historiques de l’ancienne plateforme vers BDES. Python est retenu pour cette composante car il s’agit d’un traitement ponctuel exécuté une seule fois lors de la bascule, sans maintenance continue.

2.2. Composantes hors périmètre

Composante Justification de l’exclusion

bdes-keycloak-providers

JARs tiers fournis par la communauté Keycloak. Pas de code source propre au projet.

bdes-keycloak-theme

Templates FreeMarker pour l’UI Keycloak. Tests visuels, pas unitaires.

bdes-keycloak-terraform

Configuration déclarative Keycloak (HCL). Validée par terraform plan/apply.

3. Éléments à tester

Cette section décrit, pour chaque composante, les catégories de code à couvrir par les tests unitaires et leur priorité. Les classes et modules spécifiques évoluent avec le code ; seules les couches et responsabilités à tester sont documentées ici.

3.1. API Évaluation (evaluation-api-ms)

Criticité : Haute — composante centrale du processus métier.

Couche Périmètre de test Priorité

Services

Logique de gestion des campagnes, des dossiers enseignants, des affectations aux commissions et du processus d’évaluation. Transitions de statut des dossiers et des évaluations (machine à états).

Haute

Sécurité

Vérification d’ownership (row-level security), filtrage par rôle utilisateur

Haute

Controllers REST

Codes HTTP, validation des entrées (@Valid), vérification des @PreAuthorize

Moyenne

3.2. API Référentiel (referentiel-api-ms)

Criticité : Haute — source de vérité unique pour les données de référence.

Couche Périmètre de test Priorité

Services

Opérations CRUD sur les données de référence, gestion des personnes physiques (résolution de références, contacts, adresses), gestion des formations et structures (hiérarchies parent/enfant), import bulk multi-source, correction des erreurs staging.

Haute

Controllers REST

Endpoints CRUD, endpoints d’import bulk, endpoints de gestion staging. Vérification des permissions et de la validation.

Moyenne

Filtres dynamiques

Specifications JPA pour la recherche multi-critères

Moyenne

3.3. API Notifications (notifications-api-ms)

Criticité : Moyenne — support au processus métier.

Couche Périmètre de test Priorité

Services

Envoi de notifications, gestion des templates email, consommation des événements Kafka

Moyenne

WebSocket

Authentification STOMP (interception JWT), configuration des canaux

Moyenne

Controllers REST

Endpoints de gestion des notifications

Basse

3.4. Bibliothèques partagées

Criticité : Haute — fondation transversale utilisée par tous les services.

Module Périmètre de test Priorité

commons

Machine à états des entités métier, mappers de conversion, enums

Haute

web-commons

Filtrage par audience, interception JWT, configuration CORS

Haute

redis-core

Configuration du cache, sérialisation

Basse

referentiel-client

Clients Feign inter-services, adapters, configuration du cache client

Moyenne

notifications-client

Client Feign de notifications

Basse

3.5. API Utilisateurs (bdes-users-api)

Criticité : Moyenne — synchronisation d’identités via webhooks.

Couche Périmètre de test Priorité

Services

Traitement des événements Keycloak (création, modification, suppression d’utilisateurs)

Haute

Controllers REST

Réception et validation des webhooks

Moyenne

3.6. bdes-keycloak-event-listener-spi

Criticité : Moyenne — pont entre Keycloak et le système BDES.

Couche Périmètre de test Priorité

Services

Construction du payload JSON, mise en file d’attente avec retry, envoi HTTP avec circuit breaker

Haute

Particularité : JUnit 5.10.0 + Mockito 5.5.0 standalone (pas de Spring Boot).

3.7. Frontend (bdes-frontend)

Criticité : Haute — interface utilisateur de la plateforme.

Couche Périmètre de test Priorité

Composables

Logique réactive partagée (appels API, authentification, permissions, utilitaires)

Haute

Composants Vue

Rendu DOM, événements émis, gestion des props et slots

Moyenne

Stores (Pinia)

Mutations, actions, getters, état réactif

Moyenne

Utilitaires

Fonctions pures de formatage, validation, conversion

Basse

3.8. bdes-migration

Criticité : Haute — intégrité des données migrées.

Couche Périmètre de test Priorité

Extraction

Parsing des dumps, extraction des formulaires, construction des dataclasses

Haute

Transformation

Normalisation et conversion des données brutes

Haute

Chargement

Envoi vers les APIs cibles, gestion des erreurs HTTP, idempotence

Haute

Configuration et utilitaires

Chargement de la configuration, administration Keycloak, gestion d’état, orchestration CLI

Moyenne

4. Éléments hors périmètre des tests unitaires

Élément Justification

Code généré (MapStruct)

Les mappers sont générés à la compilation par l’annotation processor MapStruct. Pas de logique manuelle à vérifier.

Code généré (Lombok)

Getters, setters, constructeurs, builders générés automatiquement. Testés indirectement via les tests de services.

Repositories Spring Data JPA

Les méthodes CRUD dérivées des noms (findByUuid, findAll) sont générées par Spring Data. Seules les requêtes custom (@Query) justifient un test.

DTOs (Records Java)

Structures de données sans logique (records Java). Validés indirectement via les tests de services et controllers.

Configuration pure (application.yml)

Fichiers de paramétrage déclaratifs. Validés au démarrage par Spring Boot.

5. Approche de test

5.1. Backend Java

L’approche de test backend repose sur JUnit 5, Mockito et AssertJ, avec le pattern AAA (Arrange / Act / Assert) comme structure de chaque test.

5.1.1. Pattern AAA

@Test
void shouldReturnPersonneWhenMatriculeExists() {
    // Arrange
    var personne = PersonnePhysique.builder().matricule("12345").build();
    when(repository.findByMatricule("12345")).thenReturn(Optional.of(personne));

    // Act
    var result = service.findByMatricule("12345");

    // Assert
    assertThat(result.matricule()).isEqualTo("12345");
}

5.1.2. Nommage des tests

Convention : should[Behavior]When[Condition]

void shouldReturnEmptyListWhenNoDataExists()
void shouldThrowExceptionWhenMatriculeIsNull()
void shouldUpdateOnlyModifiedFields()

5.1.3. Tests de services

@ExtendWith(MockitoExtension.class)
class CorpsServiceTest {

    @Mock private CorpsJpaRepository repository;
    @Mock private CorpsMapper mapper;
    @Mock private UtilsService utils;

    @InjectMocks private CorpsService service;

    // Tests...
}
  • Limite : 3 mocks maximum par test. Au-delà, c’est un signal que le code sous test a trop de responsabilités.

  • Exception documentée : certains services (PersonnePhysiqueService, FormationService) ont 5-6 dépendances. Ces cas sont acceptés et documentés.

5.1.4. Tests de controllers

@WebMvcTest(CorpsController.class)
@Import(MockSecurityConfig.class)
class CorpsControllerTest {

    @Autowired private MockMvc mvc;
    @MockBean private CorpsService service;

    @Test
    void shouldReturn200WhenFindAllWithValidAuthority() throws Exception {
        mvc.perform(get("/api/v1/corps")
                .with(jwt().authorities(new SimpleGrantedAuthority("referentiels:read"))))
            .andExpect(status().isOk());
    }

    @Test
    void shouldReturn403WhenFindAllWithoutAuthority() throws Exception {
        mvc.perform(get("/api/v1/corps")
                .with(jwt()))
            .andExpect(status().isForbidden());
    }
}
  • @WebMvcTest : charge uniquement la couche web (pas de base de données)

  • JWT simulé via SecurityMockMvcRequestPostProcessors.jwt()

  • Vérification des codes HTTP, du @PreAuthorize et de la structure JSON

5.2. Frontend (Vitest)

L’approche frontend repose sur Vitest avec deux projets de test : unit (tests unitaires purs) et integration (avec Mock Service Worker pour la simulation HTTP).

Couche Approche

Composables

Test de la logique réactive (refs, computed). Vérification des appels API via mocks.

Composants Vue

Montage via mount() / shallowMount(). Assertions sur le DOM rendu, les événements émis, les props.

Stores Pinia

Test des mutations, actions et getters en isolation. Vérification de l’état réactif.

Utilitaires

Test direct des fonctions pures (entrée → sortie).

5.3. bdes-migration (pytest)

  • conftest.py : fixtures partagées pour l’isolation

  • Tests unitaires (test_*.py) : données synthétiques, mocks des dépendances externes

  • Tests intégration (*_integration.py) : données réelles du projet

  • Limite de 3 mocks par test (même règle que le backend Java)

5.4. Anti-patterns interdits

Anti-pattern Description Correction

Assertion non significative

assertThat(service).isNotNull() — vérifie l’existence, pas le comportement

Asserter la valeur de retour métier

Test sans assertion

service.save(request); — exécute sans vérifier

Ajouter une assertion sur le résultat ou l’effet de bord

verify() sans assertion de résultat

verify(repository, times(1)).save(any()); — vérifie l’appel, pas le résultat

Vérifier le retour de la méthode testée

Mocking excessif (> 3 mocks)

Signal que le code sous test a trop de responsabilités

Refactorer le code, pas le test

Test décoratif

Un test qui vérifie que le code s’exécute sans erreur, sans vérifier un comportement

Tester le comportement métier attendu

Test de structure

assertThat(result.getClass()).isEqualTo(Response.class) — vérifie le type, pas la valeur

Asserter les valeurs métier du résultat

6. Critères de réussite et d’échec

6.1. Critères de réussite par composante

Composante Seuil couverture lignes Seuil couverture branches Tests verts

API Évaluation (evaluation-api-ms)

85%

85%

100%

API Référentiel (referentiel-api-ms)

85%

85%

100%

API Notifications (notifications-api-ms)

85%

85%

100%

Bibliothèques partagées

85%

85%

100%

API Utilisateurs (bdes-users-api)

85%

85%

100%

Event Listener Keycloak

85%

85%

100%

Frontend (bdes-frontend)

85%

85%

100%

bdes-migration

85%

85%

100%

6.2. Critères d’échec

  • Test rouge : tout test en échec bloque le build (mvn test / vitest run / pytest)

  • Couverture insuffisante : couverture inférieure au seuil de 85% lignes bloque le build (objectif projet, config JaCoCo à ajuster)

  • Régression : un test précédemment vert qui passe rouge est traité comme un défaut bloquant

6.3. Critères de suspension

  • Dépendance externe indisponible (Docker pour Testcontainers en tests d’intégration)

  • Défaut bloquant sur l’infrastructure de test (base H2, Node.js, Python)

  • Modification majeure de l’architecture nécessitant une réécriture des tests

7. Environnement de test

7.1. Backend Java

Composant Détail

JDK

Java 17 (toute distribution compatible : Temurin, Corretto, OpenJDK…​)

Build tool

Apache Maven 3.8+ (wrapper ./mvnw fourni)

Base de données test

H2 en mode compatibilité PostgreSQL (tests unitaires)

Conteneurs

Testcontainers 1.20.6 avec PostgreSQL 15 (tests d’intégration uniquement)

Profil Spring

test (fichier application-test.yml)

Sécurité

MockSecurityConfig désactivant OAuth2 Keycloak, @EnableMethodSecurity conservé

7.2. Frontend

  • Node.js 18+, Yarn

  • Vitest 3.2.3 + jsdom 26.1.0 (pas de navigateur requis)

  • Mock Service Worker 2.12.7 pour la simulation HTTP

7.3. bdes-migration

  • Python 3.9+

  • pytest >= 7.0.0, pytest-cov >= 4.0.0

7.4. Outils de couverture

Composante Outil Version Format rapport

Backend Java

JaCoCo

0.8.10

HTML + XML (target/site/jacoco/)

Frontend

@vitest/coverage-v8

3.2.3

text, json, HTML

bdes-migration

pytest-cov

>= 4.0.0

HTML

8. Livrables de test

Livrable Localisation

Code source des tests Java

bdes-backend/services/{module}/src/test/java/ et bdes-backend/libs/{module}/src/test/java/

Code source des tests users-api

bdes-users-api/src/test/java/

Code source des tests SPI Keycloak

bdes-keycloak-event-listener-spi/src/test/java/

Code source des tests frontend

bdes-frontend/tests/

Code source des tests migration

bdes-migration/tests/

Rapports JaCoCo

target/site/jacoco/ (par module Maven)

Rapport couverture frontend

Généré par npm run test:coverage

Rapport couverture migration

Généré par pytest --cov=src --cov-report=html

Appendix A: Commandes d’exécution

A.1. Backend Java (bdes-backend)

# Tous les tests du monorepo
cd bdes-backend
./mvnw test

# Tests d'un module spécifique
./mvnw test -pl services/evaluation-api-ms
./mvnw test -pl services/referentiel-api-ms
./mvnw test -pl services/notifications-api-ms

# Test d'une classe spécifique
./mvnw test -pl services/referentiel-api-ms -Dtest=CorpsServiceTest

# Test d'une méthode spécifique
./mvnw test -pl services/referentiel-api-ms -Dtest=CorpsServiceTest#shouldReturnDtoWhenUuidExists

# Tests avec rapport de couverture JaCoCo
./mvnw test jacoco:report

# Tests d'intégration uniquement
./mvnw test -Dtest=*IntegrationTest

A.2. Backend Java (bdes-users-api)

cd bdes-users-api
mvn test
mvn test jacoco:report

A.3. Backend Java (bdes-keycloak-event-listener-spi)

cd bdes-keycloak-event-listener-spi
mvn test

A.4. Frontend (bdes-frontend)

cd bdes-frontend

# Tous les tests
npm run test

# Mode watch (développement)
npm run test:watch

# Avec couverture
npm run test:coverage

A.5. bdes-migration

cd bdes-migration

# Tous les tests
pytest tests/ -v --tb=short

# Avec couverture
pytest tests/ --cov=src --cov-report=html

# Tests d'un fichier spécifique
pytest tests/test_transformers.py -v

# Tests par mot-clé
pytest tests/ -k "test_config" -v

Appendix B: Configuration JaCoCo

Extrait de la configuration jacoco-maven-plugin dans le POM parent (bdes-backend/pom.xml) :

<configuration>
    <excludes>
        <exclude>**/*MapperImpl.class</exclude>
        <exclude>**/*Application.class</exclude>
    </excludes>
</configuration>

<!-- Seuils de couverture appliqués par module -->
<execution>
    <id>check</id>
    <phase>verify</phase>
    <goals><goal>check</goal></goals>
    <configuration>
        <rules>
            <rule>
                <element>BUNDLE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.85</minimum>
                    </limit>
                    <limit>
                        <counter>BRANCH</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.85</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>