Le WordPress d'aujourd'hui, décodé pour les développeurs

Tests

Tests de caractérisation avant de refactoriser une extension santé ancienne

Sécuriser le comportement d'un module de prise de rendez-vous médicaux mal documenté avant d'y toucher, grâce à des tests de caractérisation ciblés.

Par Clément Hadrot • 24 juillet 2024 • 4 min de lecture • Aucun commentaire
Tests de caractérisation avant de refactoriser une extension santé ancienne

Aucun test n’accompagnait ce module de prise de rendez-vous médicaux, développé sept ans plus tôt par un prestataire aujourd’hui injoignable, et utilisé quotidiennement par plusieurs cabinets de radiologie pour gérer les créneaux de leurs patients. Le code fonctionnait, personne ne savait vraiment pourquoi dans certains cas limites, et une demande d’évolution imposait d’y toucher malgré tout.

Face à ce genre de situation, refactoriser directement sans filet revient à parier que le comportement observé aujourd’hui correspond bien au comportement voulu à l’origine, un pari risqué sur un module qui gère des créneaux médicaux réels. Les tests de caractérisation offrent une alternative plus prudente : documenter ce que le code fait réellement, avant de décider si cela doit changer.

Étape 1 : observer sans juger

La première étape consiste à écrire des tests qui décrivent fidèlement le comportement actuel du code, y compris ses aspects visiblement discutables. Un test de caractérisation ne dit jamais si un comportement est correct : il dit seulement ce qu’il est, aujourd’hui, avant toute modification.

public function test_comportement_actuel_creneau_deja_reserve(): void {
    $creneau = $this->create_creneau_reserve();
    $resultat = ancienne_fonction_reservation( $creneau->id, $patient_id );

    // Comportement observé, pas forcément voulu :
    // la fonction retourne true même si le créneau est déjà pris,
    // et écrase silencieusement la réservation précédente.
    $this->assertTrue( $resultat );
}

Ce test, volontairement inconfortable à lire, documente un bug réel du code existant : deux patients peuvent se voir attribuer le même créneau sans erreur visible. Plutôt que de corriger ce comportement immédiatement dans la même étape, il est d’abord figé par un test, pour être traité consciemment plus tard, en concertation avec le client sur les conséquences métier.

Étape 2 : couvrir les cas limites avant de toucher au code

L'essentiel à retenir : Observer le comportement réel avant de le juger correct ou non ; Figer les cas limites plutôt que le code lui-même ; Refactoriser étape par étape avec un filet de sécurité

Une fois le comportement principal caractérisé, la couverture s’étend méthodiquement aux cas limites : créneau à cheval sur un changement d’heure d’été, patient déjà inscrit sur trois créneaux le même jour, annulation à quelques minutes du rendez-vous. Chaque cas limite identifié dans le code, souvent via un commentaire cryptique ou une condition sans explication, devient un test dédié.

  • Les créneaux qui chevauchent minuit sont-ils gérés par jour calendaire ou par tranche de 24 heures ?
  • Que se passe-t-il si un patient annule puis réserve immédiatement le même créneau ?
  • Le fuseau horaire du serveur influence-t-il le calcul des créneaux disponibles ?

Sur ce projet, la couverture des cas limites a révélé sept comportements non documentés, dont trois ont été jugés problématiques par l’équipe métier une fois mis en lumière, et corrigés dans une étape séparée avec l’accord explicite du client.

Utiliser la couverture de code comme guide, pas comme objectif

Un outil de couverture comme pcov aide à repérer les branches de code jamais exercées par les tests de caractérisation en cours d’écriture. Une couverture de 100 % n’est pas l’objectif recherché : certaines branches mortes, du code jamais réellement atteint en production, ne méritent pas d’être caractérisées mais plutôt supprimées directement lors de la refactorisation.

Étape 3 : refactoriser avec le filet en place

Avec cette couverture en place, la refactorisation proprement dite peut commencer, module par module, en exécutant la suite de tests de caractérisation après chaque changement. Tout test qui échoue signale un changement de comportement, qu’il soit voulu ou non, et impose un arrêt pour vérifier lequel des deux cas s’applique.

wp-env run tests-cli phpunit --testsuite=caracterisation --stop-on-failure

Étape 4 : remplacer les tests de caractérisation par de vrais tests

Une fois le comportement clarifié et les corrections validées avec le client, les tests de caractérisation les plus inconfortables (ceux qui documentaient un bug volontairement laissé en l’état) sont réécrits en tests de comportement voulu, avec des noms de méthode et des commentaires qui affirment désormais ce qui est correct, plutôt que ce qui a simplement été observé.

Un test de caractérisation n’est jamais la version finale d’une suite de tests : c’est une étape de transition qui protège le code pendant qu’on apprend enfin à le comprendre.

Notre verdict

Sur un module aussi sensible qu’une prise de rendez-vous médicaux, refactoriser sans ce filet aurait exposé le client à un risque disproportionné par rapport au gain de temps espéré. Les tests de caractérisation, distincts des tests de caractérisation génériques déjà couverts par ailleurs sur des projets non spécialisés, ont ici permis de sécuriser un chantier que personne dans l’équipe n’osait entamer depuis des mois.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi