Pourquoi exécuter des tests unitaires sur un serveur CI?
Certes, au moment où quelque chose est commis à maîtriser, un développeur a déjà exécuté tous les tests unitaires avant et corrigé toutes les erreurs qui auraient pu se produire avec leur nouveau code. N'est-ce pas là l'intérêt des tests unitaires? Sinon, ils viennent de commettre du code cassé.
Certes, au moment où quelque chose est commis à maîtriser, un développeur a déjà exécuté tous les tests unitaires avant et corrigé toutes les erreurs qui auraient pu se produire avec leur nouveau code.
Ou pas. Il peut y avoir plusieurs raisons à cela:
Mais le vrai point est d'exécuter les tests sur une machine qui n'est pas la machine du développeur. Celui qui est configuré différemment.
Cela permet de détecter les problèmes où les tests et/ou le code dépendent de quelque chose de spécifique à une boîte de développeur (configuration, données, fuseau horaire, paramètres régionaux, etc.).
Autres bonnes raisons pour que les builds CI exécutent des tests:
En tant que développeur qui n'exécute pas tous les tests d'intégration et unitaires avant de s'engager dans le contrôle de code source, je proposerai ma défense ici.
Je devrais construire, tester et vérifier qu'une application fonctionne correctement sur:
Ajoutez le Fortran (avec les compilateurs Intel et GNU), Python (et ses versions varient en fonction du système d'exploitation) et les composants de script bash/bat et, eh bien , Je pense que vous pouvez voir les choses dégénérer
Donc, c'est seize machines que je devrais avoir, juste pour exécuter quelques tests quelques fois par jour. Ce serait presque un travail à plein temps de gérer l'infrastructure pour cela. Je pense que presque tout le monde conviendrait que c'est déraisonnable, surtout en le multipliant par le nombre de personnes dans le projet. Nous avons donc laissé nos serveurs CI faire le travail.
Les tests unitaires ne vous empêchent pas de commettre du code cassé, ils vous disent s'ils savoir vous avez cassé quelque chose. Les gens peuvent dire que "les tests unitaires devraient être rapides" et parler des principes et des modèles de conception et des méthodologies, mais en réalité, il est parfois préférable de laisser les ordinateurs que nous avons conçus pour des tâches répétitives et monotones faire ceux-ci et ne s'impliquer que s'ils dites-nous qu'ils ont trouvé quelque chose.
Outre l'excellente réponse Oded:
J'ai travaillé une fois sur une entreprise qui avait beaucoup de bugs sur le déploiement en raison du processus de fusion et de déploiement. Cela a été causé par un cadre propriétaire étrange qui a rendu les tests et l'IC difficiles. Ce n'était pas une expérience heureuse de constater que le code qui fonctionnait parfaitement sur le développement n'est pas arrivé directement à la production.
On pourrait penser que non, mais les développeurs sont humains et ils oublient parfois.
En outre, les développeurs ne parviennent souvent pas à extraire le dernier code. Leurs derniers tests peuvent bien fonctionner puis au moment de l'enregistrement, quelqu'un d'autre commet un changement de rupture.
Vos tests peuvent également s'appuyer sur une ressource locale (non vérifiée). Quelque chose que vos tests unitaires locaux ne détecteraient pas.
Si vous pensez que tout ce qui précède est fantaisiste, il y a un niveau au-dessus de CI (sur TFS au moins) appelé Gated où les builds qui ont des tests qui échouent sont abandonnées et ne sont pas validées dans la base de code.
au moment où quelque chose s'engage à maîtriser
J'ai généralement configuré mon CI pour qu'il s'exécute à chaque validation. Les branches ne sont pas fusionnées dans master tant que la branche n'a pas été testée. Si vous comptez sur l'exécution de tests sur le maître, cela ouvre une fenêtre pour que la construction soit interrompue.
L'exécution des tests sur une machine CI concerne des résultats reproductibles. Parce que le serveur CI a un environnement propre connu extrait de votre VCS, vous savez que les résultats du test sont corrects. Lors de l'exécution locale, vous pouvez oublier de valider le code nécessaire à leur passage, ou avoir du code non validé qui les fait passer alors qu'ils devraient échouer.
Il peut également faire gagner du temps aux développeurs en exécutant différentes suites en parallèle, en particulier si certains sont des tests lents de plusieurs minutes qui ne sont pas susceptibles d'être exécutés localement après chaque modification.
Dans mon travail actuel, notre déploiement de production est basé sur la réussite de CI à tous les tests. Les scripts de déploiement empêcheront le déploiement à moins qu'ils ne passent. Il est donc impossible d'oublier accidentellement de les exécuter.
CI faisant partie du flux de travail soulage également les développeurs. En tant que développeur, exécutez-vous généralement un linter, un analyseur statique, un test unitaire, une couverture de code et un test d'intégration pour chaque changement? CI peut, complètement automatiquement et sans avoir à y penser - réduisant la fatigue de décision.
Au moment où quelque chose est commis à maîtriser, un développeur devrait avoir déjà exécuté tous les tests unitaires ... mais que se passe-t-il s'ils ne l'ont pas? Si vous n'exécutez pas les tests unitaires sur le serveur CI, vous ne le saurez pas jusqu'à ce que quelqu'un d'autre récupère les modifications sur sa machine et découvre que les tests viennent de se casser sur eux.
De plus, le développeur peut avoir fait une erreur et référencé une ressource locale spécifique à sa machine. Lorsqu'ils archivent le code et que l'exécution du CI échoue, le problème est immédiatement identifié et peut être corrigé.
En supposant (contrairement à d'autres réponses) que les développeurs sont assez disciplinés et exécutent des tests unitaires avant de s'engager, il peut y avoir plusieurs raisons:
Il est possible d'imaginer des cas où le changement A ne rompt pas le test, et le changement B ne rompt pas le test, mais A et B ensemble le font. Si A et B sont créés par des développeurs différents, seul le serveur CI détectera le nouveau bogue. A et B peuvent même être deux parties de la même phrase plus longue.
Imaginez un train conduit par les deux locomotives A et B. Peut-être qu'une seule est plus que suffisante et c'est la solution à appliquer. Cependant, si les deux "correctifs" sont appliqués en supprimant les deux, le train ne bougera pas.
De plus, tous les développeurs n'exécutent pas tous les tests unitaires, contrairement à la plupart des bons développeurs.
Posons une question équivalente:
Pourquoi voudriez-vous construire le code sur un serveur CI?
Certes, au moment où quelque chose est commis à maîtriser, un développeur a déjà construit le code avant et corrigé toutes les erreurs qui pourraient se produire avec leur nouveau code. N'est-ce pas là l'intérêt du code du bâtiment? Sinon, ils viennent de commettre du code cassé.
Il y a plusieurs raisons de faire du CI, mais le principal point du CI est de se faire une idée de l'état du code au fil du temps. Le principal avantage (sur plusieurs) que cela offre, est que nous pouvons savoir quand la construction se casse, comprendre ce qui l'a cassé, puis le réparer.
Si le code n'est jamais cassé, pourquoi utilisons-nous même CI? Pour fournir des versions pour les tests, les versions nocturnes seraient suffisantes.