Comment conduire une revue de code
Les revues de code (et en amont, d'architecture et de conception) constituent une étape cruciale dans le processus de développement logiciel. L'analyse d'un ou plusieurs autres développeurs permet d'améliorer la qualité du travail tout en favorisant le partage de connaissances au sein de l'équipe.
Cependant, il n'est pas rare de constater que les revues de code sont souvent trop limitées. En effet, l'attention est majoritairement portée sur la vérification de la correction syntaxique et, éventuellement, du style de codage.
En Python, ces questions sont largement couvertes par des outils automatiques comme Black ou Ruff (et intégrés dans notre suite d'outils de développement en ligne de commande, Abilian Dev Tools)
Mais il est important de rappeler que l'objectif d'une revue de code va bien au-delà. Elle implique une réflexion plus large et la formulation de questions que le développeur d'origine aurait pu négliger, étant trop concentré sur la réalisation de sa tâche.
Voici une liste de questions exploratoires que nous utilisons lors des revues de code. Elles sont segmentées en 4 phases, de la conception au déploiement:
Élaboration / conception
- Quelle est l'origine de cette tâche ? Quel problème tente-t-elle de résoudre ?
- Quel est l'impact de cette tâche sur les utilisateurs finaux ? A-t-elle été conçue en tenant compte de leurs besoins ?
- Quels sont les objectifs commerciaux ou organisationnels derrière cette tâche ? Sont-ils clairement définis et alignés avec l'implémentation proposée ?
- La portée de la tâche est-elle clairement définie et compréhensible ?
- Comment la tâche a-t-elle été divisée en sous-tâches plus petites et gérables ? Cette répartition est-elle logique et efficace ?
- Quel est le comportement attendu du système dans divers scénarios ?
- Des cas extrêmes ont-ils été omis ou mal traités ?
- L'interface utilisateur a-t-elle été prise en compte de manière adéquate ?
- Comment cette tâche s'intègre-t-elle dans l'architecture globale du système ? Respecte-t-elle les principes de conception et les modèles existants ?
- Quel est l'impact de cette tâche sur les autres systèmes ou services avec lesquels elle interagit ?
- Quelles autres solutions ont été envisagées pour résoudre ce problème et pourquoi cette solution spécifique a-t-elle été choisie ?
- Comment cette fonctionnalité peut-elle évoluer dans le futur ? Est-elle suffisamment flexible pour prendre en compte des modifications ultérieures ?
- Des considérations de performance ont-elles été prises en compte dès le début de la conception ?
- Des exigences ou des contraintes de conformité réglementaire (par exemple, RGPD, HIPAA, etc.) affectent-elles la conception ?
- La conception prend-elle en compte l'accessibilité pour tous les utilisateurs, y compris ceux ayant des handicaps ou utilisant des technologies d'assistance ?
Construction
- Avez-vous une compréhension précise et complète de ce qui a été construit ?
- Comment se présente l'expérience utilisateur ? Est-elle intuitive et accessible ?
- Le code est-il cohérent avec les conventions et standards de codage de l'équipe ?
- Le code utilise-t-il efficacement les bibliothèques et les frameworks disponibles ?
- Le code est-il suffisamment documenté pour permettre à d'autres développeurs de comprendre son fonctionnement ?
- Le code est-il structuré de manière à minimiser la complexité et à maximiser la lisibilité ?
- La fonctionnalité a-t-elle été développée en suivant les principes du développement piloté par les tests (TDD) ?
- Quelle est la couverture des tests unitaires, d'intégration et fonctionnels ?
- Les tests existants ont-ils été adaptés ou de nouveaux tests ont-ils été ajoutés pour prendre en compte les modifications ?
- Le code contient-il des duplications qui pourraient être évitées en refactoring ou en extraction dans des fonctions/méthodes communes ?
- Les problèmes potentiels d'optimisation ont-ils été abordés ? Comment le code se comporte-t-il en termes de performance ? Comment le système gère-t-il la montée en charge ?
- Comment le code gère-t-il les erreurs ou les situations inattendues ? Est-ce que cela est fait de manière adéquate et transparente pour l'utilisateur ?
- Le code est-il conçu de manière à être évolutif ? Permet-il des modifications ou des extensions futures sans trop de complexité supplémentaire ?
- Le développement en local a-t-il été affecté de quelque manière que ce soit ?
- Les problèmes de sécurité ont-ils été abordés et résolus ?
Vérification
- Êtes-vous convaincu que le système fonctionne comme prévu ?
- Existe-t-il une stratégie pour l'assurance qualité ?
- Des scénarios ont-ils été laissés sans tests ?
- Quelles autres parties du système devraient faire l'objet de tests de régression ?
- Des outils d'analyse statique de code ou d'analyse de sécurité ont-ils été utilisés pour vérifier le code ?
- (Si oui) Les problèmes potentiels signalés par les outils d'analyse statique de code ont-ils été résolus ?
Déploiement / mise en production
- Avez-vous prévu un plan pour le lancement de cette fonctionnalité ? Ce plan est-il réalisable et sûr ?
- Le déploiement a-t-il été planifié pour minimiser les interruptions de service ?
- Existe-t-il un risque de perte de données ? Si oui, des mesures préventives ont-elles été prises ?
- Comment le système va-t-il se comporter pendant le déploiement ?
- Comment le déploiement sera-t-il surveillé et quels sont les critères de réussite ?
- Quelles mesures d'urgence ont été prévues en cas d'échec du déploiement ? Y a-t-il un plan de rétrogradation clair ?
- Comment les utilisateurs seront-ils informés du déploiement et des éventuelles interruptions de service ?
- Comment les problèmes qui se produisent après le déploiement seront-ils traités et par qui ?
- Quelles mesures de surveillance sont en place pour assurer le suivi du comportement de la nouvelle fonctionnalité en production ?
- Des tests de charge ou de stress ont-ils été prévus pour s'assurer que la nouvelle fonctionnalité peut gérer la demande en production ?
- Le déploiement nécessite-t-il des mises à jour de la documentation utilisateur ou des formations pour les utilisateurs finaux ?
- Comment les commentaires et les rapports de bugs des utilisateurs seront-ils recueillis et traités après le déploiement ?
- Comment seront gérées les mises à jour ou les améliorations ultérieures de cette fonctionnalité ?
En se posant ces questions lors des revues de code, on peut approfondir notre compréhension du travail accompli et anticiper les problèmes potentiels. Ces questions nous aident à nous concentrer non seulement sur le "quoi" (ce que le code fait), mais aussi sur le "pourquoi" (pourquoi il a été écrit de cette manière) et le "comment" (comment il pourrait être amélioré). Cela permet une compréhension plus profonde et une meilleure collaboration au sein de l'équipe.
Plus généralement, les bénéfices de revues de code conduites selon cette méthodologie sont les suivants:
Amélioration de la qualité du code : Les revues de code permettent de détecter et de corriger les bugs, les erreurs de logique ou les écarts avec les besoins métiers, avant que le code ne soit déployé en production. Cela contribue à réduire les coûts de débogage et de maintenance ultérieure.
Partage de connaissances : Les revues de code favorisent le partage de connaissances au sein de l'équipe. Les développeurs apprennent de nouvelles techniques et approches en examinant le travail de leurs pairs. De plus, cela garantit que plusieurs membres de l'équipe comprennent chaque partie du code, ce qui réduit le risque lié à la dépendance à une seule personne (le "bus factor").
Cohérence : Les revues de code aident à maintenir la cohérence de la base de code en s'assurant que tous les développeurs respectent les mêmes normes et conventions de codage.
Apprentissage et développement professionnel : Les revues de code sont une excellente occasion pour les développeurs, quel que soit leur niveau d'expérience, de recevoir des commentaires sur leur travail et de s'améliorer. Elles peuvent aider les nouveaux développeurs à comprendre la base de code et à assimiler les meilleures pratiques plus rapidement.
Collaboration : Les revues de code encouragent la collaboration et la communication au sein de l'équipe. Elles nécessitent une interaction régulière et ouvrent des lignes de communication qui peuvent ne pas exister autrement.
Réduction des risques : Les revues de code aident à minimiser les risques en termes de sécurité, de performances ou de compatibilité. Elles peuvent également aider à identifier en amont les problèmes d'architecture ou de conception qui pourraient être difficiles et coûteux à résoudre ultérieurement.