web-dev-qa-db-fra.com

Comment mon équipe peut-elle éviter des erreurs fréquentes après avoir refactoring?

Pour vous donner un petit fond: je travaille pour une entreprise avec environ douze Ruby sur Rails Developers (+/--/- Stagiaires). Le travail à distance est courant. Notre Le produit est composé de deux parties: un noyau plutôt gras et mince jusqu'à de gros projets de clients construits sur elle. Les projets clients élargissent généralement le noyau. L'écrasement des caractéristiques clés ne se produit pas. J'ajoute que le noyau a des parties plutôt mauvaises qui ont besoin d'urgence de refactorings. Il y a des spécifications, mais principalement pour les projets clients. La pire partie du noyau n'est pas testée (non telle qu'elle devrait être ...).

Les développeurs sont divisés en deux équipes travaillant avec un ou deux po pour chaque sprint. Habituellement, un projet client est strictement associé à l'une des équipes et du POS.

Maintenant, notre problème: plutôt fréquemment, nous vous brisons les autres. Quelqu'un de l'équipe a expandes ou refacteurs la fonctionnalité principale Y, provoquant des erreurs inattendues pour l'un des projets clients de l'équipe B. Surtout, les changements ne sont pas annoncés sur les équipes, de sorte que les bugs frappent presque toujours inattendus. L'équipe B, y compris la PO, pensa à la fonctionnalité Y pour être stable et ne l'a pas testé avant de relâcher, ignorant les changements.

Comment se débarrasser de ces problèmes? Quel genre de "technique d'annonce" pouvez-vous me recommander?

20
SDD64

Nous avons une pire partie du noyau ne sont pas testées (comme cela devrait être ...).

C'est le problème. Le refactoring efficace dépend fortement de la suite de tests automatisés. Si vous n'en avez pas, les problèmes que vous décrivez commencent à apparaître. Ceci est particulièrement important si vous utilisez une langue dynamique comme Ruby, où il n'y a pas de compilateur pour attraper des erreurs de base liées aux paramètres de passage aux méthodes.

41
Euphoric

Les réponses précédentes qui vous dirigent vers de meilleurs tests unitaires sont bonnes, mais j'estime qu'il pourrait y avoir des problèmes plus fondamentaux pour adresser. Vous avez besoin d'interfaces claires pour accéder au code de base du code des projets clients. De cette façon, si vous refactez le code central sans modifier le comportement comme observé via les interfaces, le code de l'autre équipe ne se cassera pas. Cela facilitera beaucoup plus facilement de savoir ce qui peut être réduit "en toute sécurité" et ce qui nécessite une interface, éventuellement une interface, la refonte.

5
Buhb

D'autres réponses ont mis en surbrillance des points importants (plus de tests d'unités, des équipes de fonctionnalités, des interfaces propres aux composants de base), mais il y a un point que je trouve manquant, ce qui est en version version.

Si vous gelez le comportement de votre noyau en faisant une libération1 et vous mettez cette sortie dans un système de gestion d'artefact privé2, alors tout projet client peut déclarer sa dépendance sur la version principale [~ # ~ ~] x [~ # ~], et il ne sera pas brisé par la prochaine version x + 1 .

La "politique d'annonce" réduit ensuite simplement pour avoir un fichier de modifications ainsi que chaque version ou une réunion d'équipe pour annoncer toutes les fonctionnalités de chaque nouvelle version de base.

De plus, je pense que vous devez mieux définir ce qui est "noyau" et quel sous-ensemble de cela est "clé". Vous semblez (correctement) éviter de faire de nombreuses modifications apportées aux "composants clés", mais vous autorisez des modifications fréquentes au "noyau". Afin de compter sur quelque chose, vous devez le garder stable; Si quelque chose n'est pas stable, n'appellez pas le noyau. Peut-être que je pourrais suggérer d'appeler des composants "Helper"?

[~ # ~] éditer [~ # ~] : Si vous suivez les conventions du - Système de version sémantique , puis tout Un changement incompatible dans l'API du noyau doit être marqué par A modification de la version majeure. C'est-à-dire que lorsque vous modifiez le comportement du noyau précédemment existant, ou supprimez quelque chose, non seulement ajouter quelque chose de nouveau. Avec cette convention, les développeurs savent que la mise à jour de la version '1.1' à '1.2' est sécurisée, mais de "1.x" à "2.0" est risquée et doit être soigneusement examiné.

1: Je pense que cela s'appelle un joyau, dans le monde de Ruby
2: l'équivalent à Nexus In Java ou PYPI en Python

5
logc

Comme d'autres personnes ont dit, une bonne série de tests unitaires ne résoudra pas votre problème: vous aurez du problème tout en fusionnant des changements, même si chaque équipe Test Suite passe.

Idem pour TDD. Je ne vois pas comment ça peut résoudre ce problème.

Votre solution est non technique. Vous devez définir clairement les limites "CORE" et attribuer un rôle "chien de surveillance" à quelqu'un, que ce soit le devis ou l'architecte. Toute modification du noyau doit passer par ce chien de garde. Il est responsable de s'assurer que chaque production de toutes les équipes fusionnera sans trop de dommages-intérêts collatéraux.

3
Mathieu Fortin

Bien que chaque système ait besoin de suites de tests efficaces (ce qui signifie entre autres choses, l'automatisation), et bien que ces tests, s'ils soient utilisés efficacement, attraperont ces conflits plus tôt qu'aujourd'hui, cela ne répond pas aux problèmes sous-jacents.

La question révèle au moins deux problèmes sous-jacents: la pratique consistant à modifier le "noyau" afin de satisfaire les exigences pour les clients individuels et à l'échec des équipes de communiquer et de coordonner leur intention de modifier. Aucun de ceux-ci n'est des causes profondes, et vous devrez comprendre pourquoi cela est fait avant de pouvoir le réparer.

L'une des premières choses à déterminer est de savoir si les développeurs et les gestionnaires se rendent compte qu'il y a un problème ici. Si du moins certains font, alors vous devez savoir pourquoi ils pensent non plus qu'ils ne peuvent rien faire à ce sujet, ni choisir de ne pas le faire. Pour ceux qui ne le font pas, vous pourriez essayer d'accroître leur capacité à anticiper comment leurs actions actuelles peuvent créer des problèmes futurs ou les remplacer par des personnes qui le peuvent. Jusqu'à ce que vous ayez une main-d'œuvre consciente de la manière dont les choses se passent mal, il est peu probable que vous puissiez résoudre le problème (et peut-être même pas à ce moment-là à court terme.)

Il peut être difficile d'analyser le problème des termes abstraits, du moins initialement, de la concentration sur un incident spécifique entraînant un problème et d'essayer de déterminer la manière dont cela s'est passé. À mesure que les personnes impliquées sont probablement défensives, vous devrez être alerte pour des justifications égoïstes et post-hoc afin de découvrir ce qui se passe vraiment.

Il est possible d'hésiter à mentionner parce qu'il est tellement improbable: les exigences des clients sont si disparates que la communalité est insuffisante pour justifier le code de base partagé. Si tel est le cas, vous disposez de plusieurs produits distincts et vous devriez les gérer en tant que tel, et ne pas créer un couplage artificiel entre eux.

2
sdenham

Principalement, vous avez un problème de communication (probablement également associé à un bâtiment d'équipe Problème), je pense donc qu'une solution à votre cas devrait être axée sur ... Eh bien, la communication, au lieu de techniques de développement.

Je prends pour acquis qu'il n'est pas possible de geler ni de fourche le module principal lors du démarrage d'un projet client (autrement, vous devez simplement vous intégrer dans les programmes de votre entreprise certains projets non liés à la clientèle visant à mettre à jour le module principal).

Nous sommes donc laissés avec la question d'essayer d'améliorer la communication entre les équipes. Cela peut être adressé de deux manières:

  • avec des êtres humains. Cela signifie que votre entreprise désigne une personne comme le Core Module architecte (ou quel que soit le lingo est bon pour la gestion supérieure) qui sera responsable de la qualité et de la disponibilité du code. Cette personne incarnera le noyau. Ainsi, elle sera partagée par toutes les équipes et assurera une synchronisation appropriée entre elles. En outre, elle devrait également agir en tant que critique du Code engagée dans le module principal pour maintenir sa cohérence;
  • avec des outils et des flux de travail. En imposant Intégration continue sur le noyau, vous ferez le code de base lui-même le support de communication. Cela nécessitera d'abord certains efforts (par l'ajout de suites de test automatisées à ce sujet), mais les rapports de CI nocturne constitueront une mise à jour de statut brut du module principal.

Vous pouvez en trouver plus sur CI en tant que processus de communication ici .

Enfin, vous avez un problème avec le manque de travail d'équipe au niveau de la société. Je ne suis pas un grand fan d'événements de construction d'équipes, mais cela semble être un cas où ils seraient utiles. Avez-vous des réunions au développeur à l'échelle régulière? Pouvez-vous inviter les personnes d'autres équipes à vos rétrospectives de votre projet? Ou peut-être avoir parfois des bières du vendredi soir?

1
sansuiso

Nous savons tous que les tests unitaires sont la voie à suivre. Mais nous savons aussi que la rétro-ajustement réaliste de manière réaliste à un noyau est difficile.

Une technique spécifique qui pourrait vous être utile lors de l'extension de la fonctionnalité consiste à essayer de vérifier temporairement et localement que les fonctionnalités existantes n'ont pas été modifiées. Cela peut être fait comme ceci:

Pseudo original Code:

def someFunction
   do original stuff
   return result
end

Code de test temporaire sur place:

def someFunctionNew
   new do stuff
   return result
end

def someFunctionOld
   do original stuff
   return result
end

def someFunction
   oldResult = someFunctionOld
   newResult = someFunctionNew
   check oldResult = newResult
   return newResult
end

Exécutez cette version à travers les tests de niveau système qui existent. Si tout va bien, vous savez que vous n'avez pas de choses brisées et que vous pouvez ensuite procéder à la suppression de l'ancien code. Notez que lorsque vous vérifiez l'ancien et le nouveau résultat des résultats, vous pouvez également ajouter du code permettant d'analyser les différences pour capturer les cas que vous connaissez Doit être différent en raison d'un changement prévu, tel qu'une solution de bogue.

1
Keith

"surtout, les modifications ne sont pas annoncées sur les équipes, de sorte que les bugs frappent presque toujours inattendus"

Merci de communication quiconque? Qu'en est-il (en plus de ce que tout le monde a déjà souligné que vous devriez être des tests rigoureux) en veillant à ce qu'il y a une communication appropriée? Que les gens soient conscients que l'interface qu'ils écrivent vont changer dans la prochaine version et ce que ces changements seront?
[.____] et leur donner accès au moins une intervention factice (avec une mise en œuvre vide) dès que possible au cours du développement afin de commencer à écrire leur propre code.

( Vous voulez savoir que, mais vous voulez le savoir tôt, très tôt et que les équipes se parlent-elles, coordonnent les efforts et ont un accès fréquent au travail que fait l'autre équipe (comme des engagements réguliers, pas un massif. commettre plusieurs semaines ou mois, 1-2 jours avant la livraison).
[.____] Votre bogue n'est pas dans le code, certainement pas dans le code de l'autre équipe qui ne savait pas que vous jouiez avec l'interface qu'ils écrivent. Votre bogue est dans votre processus de développement, le manque de communication et de collaboration entre personnes. Juste parce que vous êtes assis dans différentes pièces, vous ne voulez pas vous isoler des autres gars.

1
jwenting