Le code est difficile à suivre, mais il semble (généralement) bien fonctionner, du moins avec des tests superficiels. Il peut y avoir de petits bugs ici et là, mais il est très difficile de dire en lisant le code s'ils sont symptomatiques de problèmes plus profonds ou de simples solutions. Vérifier manuellement l'exactitude globale via la révision du code est cependant très difficile et prend du temps, voire du tout.
Quel est le meilleur plan d'action dans cette situation? Insister sur un do-over? Do-over partiel? Re-factoriser en premier? Résoudre les bugs uniquement et accepter la dette technique ? Effectuez une évaluation des risques sur ces options et décidez ensuite? Autre chose?
code-reviews
Brad Thomas
la source
la source
Réponses:
S'il ne peut pas être examiné, il ne peut pas passer l'examen.
Vous devez comprendre que la révision de code n'est pas destinée à la recherche de bogues. C'est à cela que sert l'assurance qualité. L'examen du code permet de s'assurer que la maintenance future du code est possible. Si vous ne pouvez même pas suivre le code maintenant, comment pouvez-vous, dans six mois, apporter des améliorations aux fonctionnalités et / ou des corrections de bugs? Trouver des bogues maintenant n’est qu’un avantage secondaire.
Si c'est trop complexe, cela viole une tonne de principes SOLID . Refactor, refactor, refactor. Découpez-le en fonctions bien nommées qui font beaucoup moins, plus simplement. Vous pouvez le nettoyer et vos scénarios de test veilleront à ce qu'il continue de fonctionner correctement. Vous avez des cas de test, non? Sinon, vous devriez commencer à les ajouter.
la source
Tout ce que vous mentionnez est parfaitement valide à signaler dans une révision de code.
Lorsque je reçois une révision de code, je vérifie les tests. Si les tests ne fournissent pas une couverture suffisante, c'est quelque chose à souligner. Les tests doivent être utiles pour garantir que le code fonctionne comme prévu et continuera de fonctionner comme prévu dans les modifications. En fait, c'est l'une des premières choses que je recherche dans une révision de code. Si vous n'avez pas prouvé que votre code répond aux exigences, je ne veux pas investir mon temps à le regarder.
Une fois qu'il y a suffisamment de tests pour le code, si le code est complexe ou difficile à suivre, c'est également quelque chose que les humains devraient examiner. Les outils d’analyse statique peuvent indiquer certaines mesures de la complexité et signaler des méthodes trop complexes, ainsi que la découverte d’erreurs potentielles dans le code (et doivent être exécutés avant une révision du code humain). Mais le code est lu et maintenu par des humains, et doit être écrit pour la maintenabilité en premier. Ce n'est que s'il existe une raison d'utiliser un code moins facile à maintenir qu'il devrait être écrit de cette manière. Si vous avez besoin d'un code complexe ou non intuitif, expliquez-le (de préférence dans le code) pourquoi le code est ainsi et proposez des commentaires utiles aux futurs développeurs pour qu'ils comprennent pourquoi et ce qu'il fait.
Idéalement, rejetez les révisions de code qui ne comportent pas de tests appropriés ou dont le code est trop complexe sans raison valable. Il peut y avoir des raisons d’affaires pour aller de l’avant, et pour cela, vous devez évaluer les risques. Si vous contractez une dette technique dans le code, insérez immédiatement des tickets dans votre système de suivi des bogues, avec quelques détails sur ce qui doit être changé et des suggestions pour le changer.
la source
Ce n'est pas à distance le but d'une révision de code. La façon de penser à une révision de code est d'imaginer qu'il y a un bogue dans le code et que vous devez le corriger. Avec cet état d'esprit, parcourez le code (en particulier les commentaires) et posez-vous la question "Est-il facile de comprendre la grande image de ce qui se passe afin que je puisse circonscrire le problème?" Si c'est le cas, c'est un laissez-passer. Sinon, c'est un échec. Il faut au moins davantage de documentation, ou éventuellement une refactorisation est nécessaire pour rendre le code raisonnablement compréhensible.
Il est important de ne pas être perfectionniste à moins que vous ne soyez sûr que c'est ce que recherche votre employeur. La plupart des codes sont si nuls qu’ils pourraient facilement être remaniés 10 fois de suite, devenant de plus en plus lisibles. Mais votre employeur ne veut probablement pas payer pour avoir le code le plus lisible au monde.
la source
Il y a de nombreuses années, mon travail consistait précisément à classer les devoirs des élèves. Et alors que beaucoup fournissaient une qualité raisonnable avec un bug ici et là, il y en avait deux qui se démarquaient. Les deux ont toujours soumis du code qui n'avait pas de bugs. Un code soumis que je pouvais lire en haut et en bas à haute vitesse et marquer comme correct à 100% avec zéro effort. L'autre code soumis, WTF après l'autre, réussissait néanmoins à éviter les bogues. Une douleur absolue à marquer.
Aujourd'hui, le second aurait son code rejeté lors d'une révision de code. Si la vérification de l'exactitude est très difficile et prend beaucoup de temps, le code pose problème. Un bon programmeur découvrirait comment résoudre un problème (cela prend du temps X) et avant de le confier à un refactorisateur de code afin que cela ne se contente pas de faire le travail, mais bien évidemment de le faire. Cela prend beaucoup moins de temps que X et vous fait gagner beaucoup de temps dans le futur. Souvent, en découvrant les bogues avant même qu'ils passent à l'étape de révision du code. Ensuite, en révisant le code beaucoup plus rapidement. Et tout le temps à l'avenir en rendant le code plus facile à adapter.
Une autre réponse a indiqué que le code de certaines personnes pourrait être modifié 10 fois, devenant ainsi plus lisible. C'est juste triste. C'est un développeur qui devrait chercher un travail différent.
la source
Est-ce que ce code ancien a été légèrement modifié? (100 lignes de code modifiées dans une base de code de 10000 lignes constituent toujours un léger changement) Parfois, il existe des contraintes de temps et les développeurs sont obligés de rester dans un cadre ancien et peu pratique, tout simplement parce qu'une réécriture complète prendrait encore plus de temps et qu'elle dépassait votre budget. . + habituellement, il y a un risque impliqué, qui peut coûter des millions de dollars lorsqu'il est mal évalué. Si c'est du code ancien, dans la plupart des cas, vous devrez vivre avec. Si vous ne le comprenez pas vous-même, parlez-leur et écoutez ce qu'ils disent, essayez de comprendre. Rappelez-vous, il peut être difficile à suivre pour vous, mais convient parfaitement pour les autres. Prends leur parti, vois-le de leur bout.
Est-ce que ce nouveau code ? En fonction des contraintes de temps, vous devriez plaider en faveur de la refactorisation autant que possible. Est-il possible de consacrer plus de temps à la révision du code si nécessaire? Vous ne devriez pas vous chronométrer à 15 minutes, avoir l’idée et passer à autre chose. Si l'auteur a passé une semaine à écrire quelque chose, vous pouvez passer de 4 à 8 heures à l'examiner. Votre but ici est de les aider à se refactorer. Vous ne retournez pas simplement le code en indiquant "refactor. Now". Voyez quelles méthodes peuvent être décomposées, essayez de trouver des idées pour introduire de nouvelles classes, etc.
la source
Souvent, les correctifs / listes de modifications "complexes" sont ceux qui font beaucoup de choses différentes à la fois. Il y a un nouveau code, un code supprimé, un code refactorisé, un code déplacé, des tests étendus; il est difficile de voir la grande image.
Un indice commun est que le correctif est énorme mais sa description est minuscule: "Implement $ FOO".
Un moyen raisonnable de gérer un tel patch consiste à demander qu’il soit divisé en une série de morceaux plus petits et autonomes. Tout comme le principe de responsabilité unique stipule qu'une fonction ne doit faire qu'une seule chose, un patch doit également se concentrer sur une seule chose.
Par exemple, les premiers correctifs peuvent contenir des modifications de refactorisation purement mécaniques qui ne font pas de modifications fonctionnelles. Les correctifs finaux peuvent ensuite se concentrer sur la mise en œuvre et les tests réels de $ FOO avec moins de distractions et de faussetures.
Pour les fonctionnalités qui nécessitent beaucoup de nouveau code, le nouveau code peut souvent être introduit dans des fragments testables qui ne modifient pas le comportement du produit jusqu'à ce que le dernier correctif de la série appelle réellement le nouveau code (un flip d'indicateur).
Pour ce qui est de faire cela avec tact, je le considère généralement comme mon problème, puis je demande l'aide de l'auteur: "J'ai du mal à suivre tout ce qui se passe ici. Pourriez-vous diviser ce patch en étapes plus petites pour m'aider à comprendre comment ensemble?" Il est parfois nécessaire de faire des suggestions spécifiques pour les plus petites étapes.
Si gros patch comme "Implement $ FOO" se transforme en une série de patchs comme:
Notez que les étapes 1 à 5 n'apportent aucune modification fonctionnelle au produit. Ils sont faciles à examiner, notamment pour vous assurer que vous avez tous les bons tests. Même si l'étape 6 est toujours "compliquée", au moins, elle est axée sur $ FOO. Et naturellement, le journal vous donne une bien meilleure idée de la façon dont $ FOO a été implémenté (et de la raison pour laquelle Frobnicate a été modifié).
la source
Comme d'autres l'ont souligné, la révision de code n'est pas vraiment conçue pour rechercher des bogues. Si vous rencontrez des problèmes lors de la révision du code, cela signifie probablement que votre couverture de tests automatisés est insuffisante (par exemple, tests unitaires / d'intégration). S'il n'y a pas assez de couverture pour me convaincre que le code fait ce qu'il est censé faire , je demande généralement plus de tests et indique le type de tests que je recherche et n'autorise généralement pas le code dans la base de code qui n'a pas une couverture adéquate. .
Si l'architecture de haut niveau est trop complexe ou n'a pas de sens, j'organise généralement une réunion avec quelques membres de l'équipe pour en discuter. Il est parfois difficile d'itérer sur une mauvaise architecture. Si le développeur était un novice, je m'assure généralement que nous examinions sa pensée à l' avance au lieu de réagir à une mauvaise demande de tirage. Cela est généralement vrai même avec des développeurs plus expérimentés si le problème n'a pas de solution évidente qui sera probablement choisie.
Si la complexité est isolée au niveau de la méthode, cela peut généralement être corrigé de manière itérative et avec de bons tests automatisés.
Un dernier point. En tant que réviseur, vous devez décider si la complexité du code est due à une complexité essentielle ou accidentelle . La complexité essentielle concerne les parties du logiciel qui sont légitimement difficiles à résoudre. La complexité accidentelle fait référence à toutes les autres parties du code que nous écrivons qui est trop complexe pour aucune raison et qui pourrait être facilement simplifiée.
Je m'assure généralement que le code avec la complexité essentielle est vraiment cela et ne peut pas être simplifié davantage. Je vise également une plus grande couverture de test et une bonne documentation pour ces parties. La complexité accidentelle devrait presque toujours être nettoyée au cours du processus de demande d'extraction, car ils constituent l'essentiel du code que nous traitons et peuvent facilement causer un cauchemar de maintenance, même à court terme.
la source
A quoi ressemblent les tests? Ils doivent être clairs, simples et faciles à lire avec idéalement une seule affirmation. Les tests doivent clairement documenter le comportement souhaité et les cas d'utilisation du code.
Si ce n'est pas bien testé, c'est un bon endroit pour commencer à examiner.
la source