Stratégie de branchement Git intégrée au processus de test / d'assurance qualité

131

Notre équipe de développement a utilisé la stratégie de branchement GitFlow et ça a été génial!

Récemment, nous avons recruté quelques testeurs pour améliorer la qualité de nos logiciels. L'idée est que chaque fonctionnalité doit être testée / QA par un testeur.

Dans le passé, les développeurs travaillaient sur des fonctionnalités sur des branches de fonctionnalités distinctes et les fusionnaient dans la developbranche une fois terminé. Le développeur testera lui-même son travail sur cette featurebranche. Maintenant, avec les testeurs, nous commençons à poser cette question

Sur quelle branche le testeur doit-il tester les nouvelles fonctionnalités?

Évidemment, il existe deux options:

  • sur la branche des fonctionnalités individuelles
  • sur la developbranche

Test sur la branche de développement

Au départ, nous pensions que c'était la voie à suivre car:

  • La fonctionnalité est testée avec toutes les autres fonctionnalités fusionnées dans la developbranche depuis le début de son développement.
  • Tout conflit peut être détecté plus tôt que plus tard
  • Cela facilite le travail du testeur, il n'a affaire qu'à une seule branche ( develop) à la fois. Il n'a pas besoin de demander au développeur quelle branche est pour quelle fonctionnalité (les branches de fonctionnalités sont des branches personnelles gérées exclusivement et librement par les développeurs concernés)

Le plus gros problème avec ceci est:

  • La developbranche est polluée d'insectes.

    Lorsque le testeur trouve des bogues ou des conflits, il les signale au développeur, qui corrige le problème sur la branche de développement (la branche de fonctionnalité a été abandonnée une fois fusionnée), et d'autres correctifs pourraient être nécessaires par la suite. Plusieurs sous-séquences commits ou fusionnent (si une branche est recréée à developnouveau hors de la branche pour corriger les bogues) rend la restauration de la fonctionnalité de la developbranche très difficile si possible. Plusieurs fonctionnalités fusionnent et sont fixées sur la developbranche à des moments différents. Cela crée un gros problème lorsque nous voulons créer une version avec seulement certaines des fonctionnalités de la developbranche

Test sur la branche de fonctionnalités

Nous avons donc réfléchi à nouveau et avons décidé de tester les fonctionnalités sur les branches de fonctionnalités. Avant de tester, nous fusionnons les modifications de la developbranche à la branche de fonctionnalité (rattrapez la developbranche). C'est bon:

  • Vous testez toujours la fonctionnalité avec d'autres fonctionnalités du grand public
  • Un développement ultérieur (par exemple, correction de bogue, résolution de conflit) ne polluera pas la developbranche;
  • Vous pouvez facilement décider de ne pas publier la fonctionnalité tant qu'elle n'a pas été entièrement testée et approuvée;

Cependant, il y a quelques inconvénients

  • Le testeur doit faire la fusion du code, et s'il y a un conflit (très probable), il doit demander de l'aide au développeur. Nos testeurs sont spécialisés dans les tests et ne sont pas capables de coder.
  • une fonctionnalité pourrait être testée sans l'existence d'une autre nouvelle fonctionnalité. Par exemple, les fonctionnalités A et B sont toutes deux testées en même temps, les deux fonctionnalités ne se connaissent pas car aucune d'elles n'a été fusionnée dans la developbranche. Cela signifie que vous devrez à nouveau tester la developbranche lorsque les deux fonctionnalités sont fusionnées dans la branche de développement de toute façon. Et vous devez vous rappeler de tester cela à l'avenir.
  • Si les fonctionnalités A et B sont toutes les deux testées et approuvées, mais lors de la fusion, un conflit est identifié, les deux développeurs des deux fonctionnalités pensent que ce n'est pas sa propre faute / travail car sa fonctionnalité a dépassé le test. Il y a une surcharge supplémentaire dans la communication, et parfois celui qui résout le conflit est frustré.

Ci-dessus, notre histoire. Avec des ressources limitées, j'aimerais éviter de tout tester partout. Nous cherchons toujours une meilleure façon de faire face à cela. J'adorerais entendre comment les autres équipes gèrent ce genre de situations.

David Lin
la source
5
Cette question semble mieux convenir aux programmeurs , car elle ne traite pas d'un problème de programmation, mais plutôt d'un processus de développement. Quelqu'un peut-il le migrer?
2
Notre modèle est exactement le même. Je suis intéressé à savoir comment votre équipe d'assurance qualité signale les problèmes sur les branches de fonctionnalités différemment des problèmes sur le terrain ou des problèmes lors du processus UAT (si vous en avez un). Nous utilisons Atlassian JIRA et nous avons un flux de travail différent pour les deux.
void.pointer
2
Décider la même chose maintenant. De plus, comme notre environnement est une application java spring, la construction et le déploiement dans l'environnement de test prennent environ 20 minutes. Heureux quelqu'un a posé les mêmes doutes que moi.
digao_mb
Le premier inconvénient n'est pas inhérent au processus de test sur les branches de fonctionnalités. Des outils tels que Github Enterprise et Bitbucket ont la capacité d'exiger une approbation pour les pull requests et la personne responsable du contrôle qualité peut approuver le signalement au développeur qu'il est libre de fusionner dans le développement.
Derek Greer

Réponses:

102

La façon dont nous procédons est la suivante:

Nous testons les branches de fonctionnalités après avoir fusionné le dernier code de branche de développement sur elles. La raison principale est que nous ne voulons pas «polluer» le code de branche de développement avant qu'une fonctionnalité ne soit acceptée. Au cas où une fonctionnalité ne serait pas acceptée après les tests, mais nous aimerions publier d'autres fonctionnalités déjà fusionnées lors du développement, ce serait l'enfer. Develop est une branche à partir de laquelle une version est faite et devrait donc mieux être dans un état libérable. La version longue est que nous testons en plusieurs phases. Plus analytiquement:

  1. Le développeur crée une branche de fonctionnalité pour chaque nouvelle fonctionnalité.
  2. La branche de fonctionnalités est (automatiquement) déployée sur notre environnement TEST avec chaque commit que le développeur doit tester.
  3. Lorsque le développeur a terminé le déploiement et que la fonctionnalité est prête à être testée, il fusionne la branche de développement sur la branche de fonctionnalité et déploie la branche de fonctionnalité qui contient toutes les dernières modifications de développement sur TEST.
  4. Le testeur teste TEST. Quand il a terminé, il "accepte" l'histoire et fusionne la branche de fonctionnalité lors du développement. Comme le développeur avait précédemment fusionné la branche de développement sur la fonctionnalité, nous ne nous attendons normalement pas à trop de conflits. Cependant, si tel est le cas, le développeur peut vous aider. C'est une étape délicate, je pense que le meilleur moyen de l'éviter est de garder les fonctionnalités aussi petites / spécifiques que possible. Différentes fonctionnalités doivent éventuellement être fusionnées, d'une manière ou d'une autre. Bien entendu, la taille de l'équipe joue un rôle sur la complexité de cette étape.
  5. La branche de développement est également (automatiquement) déployée sur TEST. Nous avons une politique selon laquelle même si les constructions de branche de fonctionnalités peuvent échouer, la branche de développement ne doit jamais échouer.
  6. Une fois que nous avons atteint un gel des fonctionnalités, nous créons une version de develop. Celui-ci est automatiquement déployé sur STAGING. Des tests approfondis de bout en bout y ont lieu avant le déploiement en production. (ok peut-être j'exagère un peu, ils ne sont pas très étendus mais je pense qu'ils devraient l'être). Idéalement, les bêta-testeurs / collègues, c'est-à-dire les vrais utilisateurs devraient y faire des tests.

Que pensez-vous de cette approche?

Aspasie
la source
2
Comment pouvons-nous nous assurer que feature1 et feature2 qui ont été testés indépendamment sont également compatibles (comme mentionné dans la question)?
Kumar Deepak
2
nous le faisons indirectement, en fusionnant l'un puis l'autre pour se développer. C'est l'étape 4 du processus ci-dessus et elle a à voir avec l'ordre chronologique. Donc, si la fonctionnalité 2 est prête à être fusionnée mais que la fonctionnalité 1 a déjà été fusionnée, le développeur et le testeur de la fonctionnalité 2 doivent s'assurer que leur fusion fonctionnera.
Aspasia
1
Je pense que de toute façon, selon ce modèle de branchement git, vous n'êtes pas censé fusionner deux branches de fonctionnalités l'une avec l'autre.
Aspasia
1
Nous avons rencontré des problèmes à l'étape 6, en particulier en période de crise avec plusieurs fonctionnalités déplacées à développer, en raison de fusions non triviales qui se produisent après que le contrôle qualité a signé la branche de fonctionnalités, malgré la fusion de devlop pour la fonctionnalité le plus tard possible. J'ai commenté un peu plus en détail ici: stackoverflow.com/a/25247382/411282
Joshua Goldberg
8
Avez-vous un environnement TEST complet (base de données, serveur, client, etc.) pour chaque branche de fonctionnalités? Ou partagent-ils l'environnement et ont juste des noms différents (par exemple app-name_feature1- app-name_feature2, etc.)
hinneLinks
41

Avant le test, nous fusionnons les modifications de la branche de développement à la branche de fonctionnalité

Non, surtout si «nous» est le testeur QA. La fusion impliquerait de résoudre les conflits potentiels, ce qui est mieux fait par les développeurs (ils connaissent leur code), et non par un testeur QA (qui devrait procéder au test le plus rapidement possible).

Faites en sortefeaturedevel que le développeur fasse un rebase de sa branche par-dessus et poussez cette featurebranche (qui a été validée par le développeur comme compilant et travaillant au-dessus de l' develétat de branche le plus récent ).
Cela permet:

  • une intégration très simple sur la branche des fonctionnalités (fusion rapide triviale).
  • ou, comme recommandé par Aspasia ci-dessous dans les commentaires , une pull request (GitHub) ou une requête de fusion (GitLab) : le mainteneur fait une fusion entre la branche PR / MR de la fonctionnalité et develop, mais seulement si aucun conflit n'est détecté par GitHub / GitLab.

Chaque fois que le testeur détecte un bogue, il le signale au développeur et supprime la branche de fonctionnalité actuelle.
Le développeur peut:

  • corriger le bug
  • rebase au-dessus d'une branche de développement récemment récupérée (encore une fois, pour être sûr que son code fonctionne en intégration avec d'autres fonctionnalités validées)
  • pousser la featurebranche.

Idée générale: assurez-vous que la partie fusion / intégration est effectuée par le développeur, en laissant les tests au QA.

VonC
la source
Êtes-vous en train de dire "n'utilisez pas la fusion, utilisez plutôt le rebase"? Si tel est le cas, je suis confus, étant donné la FAQ Git sur la différence entre les deux: git.wiki.kernel.org/index.php
Vicki Laidler
1
@VickiLaidler oui, si la branche de fonctionnalité est rejetée par QA, le développeur doit rebaser, pas fusionner ( stackoverflow.com/a/804178/6309 )
VonC
1
@VonC Je suis tout à fait d'accord mais il y a quelques problèmes: 1) La suppression de la branche a un impact sur d'autres outils, comme les demandes de retrait de Stash (la suppression de la branche ferme le PR). Préférez la force de poussée. 2) S'il s'agit d'une grande branche de fonctionnalités où pendant sa vie deux personnes ont collaboré, les fusions auraient été préférées au rebasage. Le recalculer à la fin crée un cauchemar de conflit car les validations de fusion seront supprimées, et si le code dépendait de ces modifications de fusion, il n'est pas trivial de le corriger
void.pointer
1
En repensant à ma réponse, je ferais également un rebase et non une fusion pour une histoire plus propre.
Aspasia
1
@Aspasia Bons points. J'ai inclus des pull-requests dans la réponse pour plus de visibilité.
VonC
12

La meilleure approche est l'intégration continue , où l'idée générale est de fusionner les branches de fonctionnalités dans la branche développeur aussi souvent que possible. Cela réduit les frais généraux liés à la fusion des douleurs.

Fiez-vous autant que possible aux tests automatisés et faites démarrer automatiquement les builds avec les tests unitaires de Jenkins. Demandez aux développeurs de faire tout le travail de fusion de leurs modifications dans la branche principale et de fournir des tests unitaires pour tout leur code.

Les testeurs / QA peuvent participer à des revues de code, cocher des tests unitaires et écrire des tests d'intégration automatisés à ajouter à la suite de régression à mesure que les fonctionnalités sont terminées.

Pour plus d'informations, consultez ce lien .

Johnny Z
la source
Vous pouvez toujours faire du CI avec des branches + rebasage dans Git.
void.pointer
9

Nous utilisons ce que nous appelons «or», «argent» et «bronze». Cela pourrait être appelé prod, staging et qa.

J'en suis venu à appeler cela le modèle du melting-pot. Cela fonctionne bien pour nous car nous avons un énorme besoin d'assurance qualité dans le domaine commercial, car les exigences peuvent être difficiles à comprendre par rapport aux aspects techniques.

Lorsqu'un bogue ou une fonctionnalité est prêt à être testé, il passe en "bronze". Cela déclenche une build jenkins qui pousse le code dans un environnement pré-construit. Nos testeurs (pas des super techniciens d'ailleurs) viennent de frapper un lien et ne se soucient pas du contrôle de source. Cette version exécute également des tests, etc. Nous avons fait des allers-retours sur cette version en poussant le code vers l'environnement testing \ qa si les tests (unité, intégration, sélénium) échouent. Si vous testez sur un système séparé (nous l'appelons lead), vous pouvez empêcher que les modifications soient transmises à votre environnement QA.

La crainte initiale était que nous ayons beaucoup de conflits entre ces fonctionnalités. Cela se produit lorsque la fonctionnalité X donne l'impression que la fonctionnalité Y est en panne, mais elle est assez rare et aide réellement. Cela permet d'obtenir une large gamme de tests en dehors de ce qui semble être le contexte du changement. Plusieurs fois, par chance, vous découvrirez comment votre changement affecte le développement parallèle.

Une fois qu'une fonctionnalité passe le contrôle qualité, nous la déplaçons vers «argent» ou mise en scène. Une compilation est exécutée et les tests sont exécutés à nouveau. Chaque semaine, nous poussons ces changements dans notre "or" ou arbre de production, puis nous les déployons dans notre système de production.

Les développeurs commencent leurs modifications à partir de l'arbre d'or. Techniquement, vous pouvez commencer à partir de la mise en scène, car ceux-ci vont bientôt augmenter.

Les correctifs d'urgence sont placés directement dans l'arbre d'or. Si un changement est simple et difficile à QA, il peut aller directement dans l'argent qui trouvera son chemin vers l'arbre de test.

Après notre sortie, nous poussons les changements de l'or (prod) au bronze (test) juste pour que tout soit synchronisé.

Vous voudrez peut-être rebaser avant de pousser dans votre dossier intermédiaire. Nous avons constaté que la purge de l'arbre de test de temps en temps le maintient propre. Il y a des moments où des fonctionnalités sont abandonnées dans l'arbre de test, surtout si un développeur s'en va.

Pour les grandes fonctionnalités multi-développeurs, nous créons un référentiel partagé séparé, mais le fusionnons dans l'arborescence de test de la même manière lorsque nous sommes tous prêts. Les choses ont tendance à rebondir à partir du contrôle qualité, il est donc important de garder vos ensembles de modifications isolés afin que vous puissiez les ajouter, puis les fusionner / écraser dans votre arbre de préparation.

"Baking" est également un bel effet secondaire. Si vous avez un changement fondamental que vous voulez laisser reposer pendant un certain temps, il y a une belle place pour cela.

Gardez également à l'esprit que nous ne conservons pas les versions précédentes. La version actuelle est toujours la seule version. Même ainsi, vous pourriez probablement avoir un arbre de cuisson maître où vos testeurs ou votre communauté peuvent voir comment les différents contributeurs interagissent.

Eric Twilegar
la source
1

Je ne me fierais pas uniquement aux tests manuels. J'automatiserais le test de chaque branche de fonctionnalité avec Jenkins. J'ai installé un laboratoire VMWare pour exécuter des tests Jenkins sur Linux et Windows pour tous les navigateurs. C'est vraiment une formidable solution de test multi-navigateur et multi-plateforme. Je teste le fonctionnement / l'intégration avec Selenium Webdriver. Mes tests de sélénium fonctionnent sous Rspec. Et je les ai écrits spécialement pour être chargés par jRuby sur Windows. J'exécute des tests unitaires traditionnels sous Rspec et des tests Javascript sous Jasmine. J'ai configuré des tests sans tête avec Phantom JS.

Natus Drew
la source
1

Dans notre entreprise, nous ne pouvons pas utiliser le développement agile et avons besoin d'une approbation pour chaque changement par entreprise, cela pose beaucoup de problèmes.

Notre approche pour travailler avec GIT est la suivante;

Nous avons implémenté "Git Flow" dans notre entreprise. Nous utilisons JIRA et seuls les billets JIRA approuvés doivent être mis en production. Pour l'approbation du test, nous l'avons étendu avec une branche de test séparée.

Les étapes de traitement d'un ticket JIRA sont:

  1. Créer une nouvelle branche à partir de Develop-Branch
  2. Faire les changements de code sur la branche de fonctionnalité
  3. Tirez de la fonctionnalité les modifications vers la branche Test / QA
  4. Après l'approbation de l'entreprise, nous intégrons le changement de la branche de fonctionnalités au développement
  5. Le développement va fréquemment dans une release puis finalement master branch

Le fractionnement de chaque demande dans une propre fonctionnalité garantit que seules les modifications approuvées sont passées en production.

Le processus complet ressemble à ceci: entrez la description de l'image ici

Christian Müller
la source