Comment la livraison continue peut-elle fonctionner dans la pratique?

22

La livraison continue semble bonne, mais mes années d'expérience en développement logiciel suggèrent qu'en pratique cela ne peut pas fonctionner.

(Edit: Pour être clair, j'ai toujours beaucoup de tests qui s'exécutent automatiquement. Ma question est de savoir comment obtenir la confiance nécessaire pour livrer à chaque enregistrement, ce qui, je crois, est la forme complète du CD. L'alternative n'est pas les cycles d'un an Ce sont des itérations chaque semaine (que certains pourraient considérer comme encore CD si elles sont faites correctement), deux semaines ou mois; y compris un AQ à l'ancienne à la fin de chacune, complétant les tests automatisés.)

  • Une couverture complète du test est impossible. Vous devez consacrer beaucoup de temps - et le temps c'est de l'argent - pour chaque petite chose. C'est précieux, mais le temps pourrait être consacré à contribuer à la qualité par d'autres moyens.
  • Certaines choses sont difficiles à tester automatiquement. Par exemple, GUI. Même Selenium ne vous dira pas si votre interface graphique est bancale. L'accès à la base de données est difficile à tester sans appareils encombrants, et même cela ne couvrira pas les cas étranges dans votre stockage de données. De même la sécurité et bien d'autres choses. Seul le code de la couche métier est effectivement testable à l'unité.
  • Même dans la couche métier, la plupart des codes ne sont pas des fonctions simples dont les arguments et les valeurs de retour peuvent être facilement isolés à des fins de test. Vous pouvez passer beaucoup de temps à créer des objets fictifs, ce qui pourrait ne pas correspondre aux implémentations réelles.
  • Les tests d'intégration / fonctionnels complètent les tests unitaires, mais leur exécution prend beaucoup de temps car ils impliquent généralement la réinitialisation de l'ensemble du système à chaque test. (Si vous ne réinitialisez pas, l'environnement de test est incohérent.)
  • La refactorisation ou tout autre changement casse de nombreux tests. Vous passez beaucoup de temps à les réparer. S'il s'agit de valider des changements de spécifications significatifs, c'est bien, mais les tests échouent souvent en raison de détails d'implémentation de bas niveau sans signification, pas de choses qui fournissent vraiment des informations importantes. Souvent, le peaufinage vise à retravailler les éléments internes du test, et non à vérifier réellement les fonctionnalités testées.
  • Les rapports de terrain sur les bogues ne peuvent pas être facilement mis en correspondance avec la micro-version précise du code.
Joshua Fox
la source
Cela fonctionne très bien pour Etsy slideshare.net/OReillyOSCON/… !
YoTsumi
4
La livraison continue ne nécessite pas de test (mais cela aide). Cela se réfère au fait que les choses que vous construisez régulièrement POURRAIENT être expédiées au client si nécessaire.
Il est intéressant de noter que vos objections à la livraison continue se concentrent massivement sur les tests en tant qu'élément de CD. Cependant, ce n'est qu'une partie du puzzle: vous avez besoin d'outils internes compétents, de développeurs engagés dans des inspections qualité rigoureuses, d'une approche de priorisation étendue dans vos tests automatisés, sans parler d'un solide soutien organisationnel. Cela peut être fait, mais il faut beaucoup de gens pour s'engager dans la cause.
Stephen Gross
1
@Stephen Oui, je me concentre sur les tests, car je suis d'accord sur tous les autres aspects. Je suis également en faveur des tests. Je ne vois tout simplement pas comment vous pouvez avoir suffisamment de confiance pour déployer chaque enregistrement.
Joshua Fox
@ Thorbjørn Ravn Andersen. Certes, le CD semble nécessiter des tests. Comment pouvez-vous avoir la confiance nécessaire pour expédier automatiquement chaque enregistrement sans lui.
Joshua Fox

Réponses:

29

mes années d'expérience en développement logiciel suggèrent qu'en pratique cela ne peut pas fonctionner.

L'as tu essayé? Dave et moi avons écrit le livre sur la base de nombreuses années d'expérience collective, à la fois de nous-mêmes et d'autres personnes âgées de ThoughtWorks, en train de faire les choses dont nous discutons. Rien dans le livre n'est spéculatif. Tout ce dont nous discutons a été testé et testé même sur de grands projets distribués. Mais nous ne vous suggérons pas de le croire. Bien sûr, vous devriez l'essayer vous-même, et veuillez écrire ce que vous trouvez qui fonctionne et ce qui ne fonctionne pas, y compris le contexte pertinent, afin que d'autres puissent apprendre de vos expériences.

La livraison continue met l'accent sur les tests automatisés. Nous passons environ 1/3 du livre à en parler. Nous le faisons parce que l'alternative - les tests manuels - est coûteuse et sujette aux erreurs, et n'est en fait pas un excellent moyen de créer un logiciel de haute qualité (comme l'a dit Deming, «Cesser de dépendre de l'inspection de masse pour atteindre la qualité. Améliorer le processus et renforcer la qualité dans le produit en premier lieu ")

Une couverture complète du test est impossible. Vous devez consacrer beaucoup de temps - et le temps c'est de l'argent - pour chaque petite chose. C'est précieux, mais le temps pourrait être consacré à contribuer à la qualité par d'autres moyens.

Bien sûr, une couverture de test complète est impossible, mais quelle est l'alternative: une couverture de test zéro? Il y a un compromis. Quelque part entre les deux se trouve la bonne réponse pour votre projet. Nous constatons qu'en général, vous devez vous attendre à passer environ 50% de votre temps à créer ou à maintenir des tests automatisés. Cela peut sembler coûteux jusqu'à ce que vous considériez le coût des tests manuels complets et de la correction des bogues qui sortent pour les utilisateurs.

Certaines choses sont difficiles à tester automatiquement. Par exemple, GUI. Même Selenium ne vous dira pas si votre interface graphique est bancale.

Bien sûr. Découvrez le quadrant de test de Brian Marick. Vous devez toujours effectuer des tests exploratoires et des tests d'utilisabilité manuellement. Mais c'est pour cela que vous devriez utiliser vos êtres humains chers et précieux - pas pour les tests de régression. La clé est que vous devez mettre en place un pipeline de déploiement afin de ne prendre la peine d'exécuter que des validations manuelles coûteuses sur des builds qui ont réussi une suite complète de tests automatisés. Ainsi, vous réduisez à la fois le montant d'argent que vous dépensez pour les tests manuels et le nombre de bogues qui parviennent jamais à un test manuel ou à une production (délai auquel ils sont très coûteux à corriger). Les tests automatisés effectués correctement sont beaucoup moins chers sur la durée de vie du produit, mais bien sûr, il s'agit d'une dépense en capital qui s'amortit avec le temps.

L'accès à la base de données est difficile à tester sans appareils encombrants, et même cela ne couvrira pas les cas étranges dans votre stockage de données. De même la sécurité et bien d'autres choses. Seul le code de la couche métier est effectivement testable à l'unité.

L'accès à la base de données est testé implicitement par vos tests d'acceptation fonctionnelle basés sur des scénarios de bout en bout. La sécurité nécessitera une combinaison de tests automatisés et manuels - tests de pénétration automatisés et analyse statique pour trouver (par exemple) des dépassements de tampon.

Même dans la couche métier, la plupart des codes ne sont pas des fonctions simples dont les arguments et les valeurs de retour peuvent être facilement isolés à des fins de test. Vous pouvez passer beaucoup de temps à créer des objets fictifs, ce qui pourrait ne pas correspondre aux implémentations réelles.

Bien sûr, les tests automatisés sont chers si vous construisez mal votre logiciel et vos tests. Je recommande fortement de consulter le livre "Un logiciel orienté objet en pleine croissance, guidé par des tests" pour comprendre comment le faire correctement afin que vos tests et votre code soient maintenables dans le temps.

Les tests d'intégration / fonctionnels complètent les tests unitaires, mais leur exécution prend beaucoup de temps car ils impliquent généralement la réinitialisation de l'ensemble du système à chaque test. (Si vous ne réinitialisez pas, l'environnement de test est incohérent.)

L'un des produits sur lesquels je travaillais a une suite de 3 500 tests d'acceptation de bout en bout qui prennent 18 heures pour s'exécuter. Nous l'exécutons en parallèle sur une grille de 70 cases et obtenons un retour sur 45m. Encore plus longtemps que l'idéal, c'est pourquoi nous l'exécutons en tant que deuxième étape du pipeline après que les tests unitaires se soient déroulés en quelques minutes afin de ne pas gaspiller nos ressources sur une construction dont nous n'avons pas un niveau de base confiance en.

La refactorisation ou tout autre changement casse de nombreux tests. Vous passez beaucoup de temps à les réparer. S'il s'agit de valider des modifications de spécifications significatives, c'est bien, mais les tests échouent souvent en raison de détails d'implémentation de bas niveau sans signification, pas de choses qui fournissent vraiment des informations importantes. Souvent, le peaufinage vise à retravailler les éléments internes du test, et non à vérifier réellement les fonctionnalités testées.

Si votre code et vos tests sont bien encapsulés et faiblement couplés, le refactoring ne cassera pas beaucoup de tests. Nous décrivons dans notre livre comment faire la même chose pour les tests fonctionnels aussi. Si vos tests d'acceptation échouent, c'est un signe que vous manquez un ou plusieurs tests unitaires, donc une partie du CD implique d'améliorer constamment votre couverture de test pour essayer de trouver des bogues plus tôt dans le processus de livraison où les tests sont plus fins et les les bogues sont moins chers à corriger.

Les rapports de terrain sur les bogues ne peuvent pas être facilement mis en correspondance avec la micro-version précise du code.

Si vous testez et publiez plus fréquemment (une partie de l'intérêt du CD), il est relativement simple d'identifier le changement qui a causé le bogue. L'intérêt du CD est d'optimiser le cycle de rétroaction afin que vous puissiez identifier les bogues dès que possible après leur archivage au contrôle de version - et en fait, de préférence avant leur archivage (c'est pourquoi nous exécutons les tests de construction et unitaires avant l'enregistrement).

Jez Humble
la source
Merci pour votre réponse. Oui, je crois aux tests. Mes projets ont une bonne couverture de code à partir de tests automatisés exécutés avec la version quotidienne. Je dis juste que vous avez besoin d'une sorte d'itération avant de sortir. "Vous devez toujours effectuer des tests exploratoires ... manuellement." Je ne comprends pas. Un système de CD complet se déploie à chaque enregistrement. Comment pouvez-vous faire cela si vous incluez des tests manuels?
Joshua Fox
3
J'aime faire la distinction entre la livraison continue et le déploiement continu. Voici la différence. La livraison continue signifie que vous gardez le système prêt à la production à tout moment et que vous pouvez le libérer sur demande en appuyant sur un bouton. La libération est une décision commerciale. Le déploiement continu est un cas limite où vous publiez chaque bonne version (notez pas tous les enregistrements - certains enregistrements ne donnent pas lieu à une version libérable). Dans les deux cas, vous pouvez inclure des validations manuelles: la clé est le concept du pipeline de déploiement .
Jez Humble,
Concernant "L'accès à la base de données est testé implicitement par vos tests d'acceptation fonctionnelle basés sur des scénarios de bout en bout." Le problème clé est que cela est implicite . Les gens semblent satisfaits de cela, mais c'est une approche qui fait perdre beaucoup de temps; au lieu de dire le problème "C'est ce que j'attendais de la base de données et je l'ai obtenu à la place", il dit "Quelque chose s'est cassé dans l'une des 100 couches".
atoth
11

Tout d'abord, le CD nécessite un gros ajustement mental - vous devez admettre que parfois les choses se cassent, quoi que vous fassiez. À la fin de la journée, vous ne pouvez pas prouver un résultat négatif.

Une fois que vous avez dépassé cela, vous vous rendez compte que vous avez besoin d'outils et de procédures pour a) détecter ces erreurs très rapidement et b) annuler ou déployer la mise à jour de manière très efficace. De plus, si vous buvez vraiment le cocktail de CD, vous apportez vraiment beaucoup de petits changements pointus qui sont faciles à annuler et ne devraient pas être en mesure d'introduire des bogues majeurs à l'échelle de l'application. Même les gars qui pratiquent vraiment le CD gèrent les changements majeurs d'une manière plus traditionnelle.

Wyatt Barnett
la source
msgstr "les petits ... changements ... ne devraient pas pouvoir introduire de bogues à l 'échelle de l' application". Même dans un code bien factorisé, cela peut arriver. Par exemple, vous ajoutez un div qui pousse un autre div hors de vue dans un navigateur particulier. Par exemple, une valeur nulle apparaît dans un cas d'angle inattendu, levant une exception et empêchant du tout le rendu de l'interface graphique. Oui, vous devriez tester tout ce qui est possible, comme moi, mais inévitablement, des bugs se produisent et de petits bugs peuvent perturber toute l'application.
Joshua Fox
Mais ils sont toujours faciles à trouver et à corriger, ce qui est le point le plus important.
Wyatt Barnett
2

Chaque système comporte des risques et chaque risque a des coûts potentiels. Si le coût d'un risque minuscule, du type de celui qui peut prendre des mois ou des années à trouver dans les tests approfondis et l'AQ, est suffisamment élevé (le logiciel de votre stimulateur cardiaque), vous ne livrez pas sans une longue période de test d'un libération gelée. Si le coût de l'échec est suffisamment faible, vous expédiez peut-être en continu sans aucun test (la page Facebook de votre chat).

hotpaw2
la source
Oui. Pour la plupart des applications de production, le risque se situe quelque part entre les deux. Et il me semble que le risque est tel que nous ne voudrions pas déployer à chaque check-in, même avec des tests automatisés. Il semble qu'une ronde d'AQ soit toujours nécessaire. Mais des sorties à peu près hebdomadaires me semblent réalisables.
Joshua Fox
1

Une couverture complète du test est impossible. Vous devez consacrer beaucoup de temps - et le temps c'est de l'argent - pour chaque petite chose. C'est précieux, mais le temps pourrait être consacré à contribuer à la qualité par d'autres moyens.

Vous n'avez pas besoin d'une couverture à 100%, vous avez besoin de suffisamment pour avoir confiance en votre système, que les changements à un seul endroit ne casseront pas les choses que vous avez précédemment prouvées.

Certaines choses sont difficiles à tester automatiquement. Par exemple, GUI. Même le sélénium ne le fera pas
vous dira pas si votre interface graphique est bancale. L'accès à la base de données est difficile à tester sans appareils encombrants, et même cela ne couvrira pas les cas étranges dans votre stockage de données.

L'accès à la base de données est cependant trivial à écrire. Vous ne devriez pas avoir besoin de nombreux tests sur votre couche de données car il s'agit simplement d'obtenir et de définir des données. Le plus important est de s'assurer qu'en cas d'échec, il annule et enregistre le problème afin que vous puissiez le résoudre.

De même la sécurité et bien d'autres choses. Seul le code de la couche métier est effectivement testable à l'unité. Même dans la couche métier, la plupart des codes ne sont pas des fonctions simples dont les arguments et les valeurs de retour peuvent être facilement isolés à des fins de test.

Beaucoup de vos fonctions / classes sont alors trop volumineuses. Ils doivent être écrits pour être testables.

Vous pouvez passer beaucoup de temps à créer des objets fictifs, ce qui pourrait ne pas correspondre aux implémentations réelles.

Les E / S de l'objet factice doivent cependant correspondre à ce qui est attendu. Ce qui se passe à l'intérieur sans importance.

Les tests d'intégration / fonctionnels complètent les tests unitaires, mais leur exécution prend beaucoup de temps car ils impliquent généralement la réinitialisation de l'ensemble du système à chaque test. (Si vous ne réinitialisez pas, l'environnement de test est incohérent.)

Ceux-ci ne devraient pas être exécutés tout le temps. Au besoin.

La refactorisation ou tout autre changement casse de nombreux tests. Vous passez beaucoup de temps à les réparer. S'il s'agit de valider des modifications de spécifications significatives, c'est bien, mais les tests échouent souvent en raison de détails d'implémentation de bas niveau sans signification, pas de choses qui fournissent vraiment des informations importantes. Souvent, le peaufinage vise à retravailler les éléments internes du test, et non à vérifier réellement les fonctionnalités testées.

Ensuite, votre code est trop étroitement couplé et vos tests sont mal écrits.

Les rapports de terrain sur les bogues ne peuvent pas être facilement mis en correspondance avec la micro-version précise du code.

Vous ne savez pas où vous en êtes ici? S'il y a un bug, écrivez un test pour montrer son existence, puis corrigez-le.

CaffGeek
la source
"Les E / S de l'objet factice doivent correspondre à ce qui est attendu." pour la production et une fois pour les OM)
Joshua Fox
1

Fonctionne bien pour nous, mais nos clients sont principalement internes. Plusieurs versions effectuées pendant la journée, les versions cassées ne sont pas tolérées, le mécanisme de démarrage Web est utilisé pour que les utilisateurs obtiennent la dernière version à chaque lancement. Une chose est que le CD fait disparaître beaucoup de problèmes. Oui, vous avez des problèmes de compatibilité tout le temps, cependant, puisque vous ne déployez que de petites modifications à chaque fois, les problèmes sont vraiment faciles à comprendre. Le niveau de stress du CD est BEAUCOUP plus bas que lorsque nous avons fait de grosses mises à jour et nous devions espérer que tout allait bien car il y aurait tellement de code à revoir en cas de casse.

Brian Knoblauch
la source
-4

Pour être honnête, TOUS les logiciels sont en livraison continue! La chose la plus importante est de la sortir! Faites en sorte que vos utilisateurs l'utilisent et hiérarchisez les demandes de fonctionnalités et l'élimination des bogues après cela.

"Navire de vrais artistes"
- Steve Jobs.

Gary Willoughby
la source
l'alternative au CD n'est pas les cycles d'un an. Ce sont des itérations chaque semaine, deux semaines ou mois.
Joshua Fox