Dans ma solution C #, j'ai un projet de test contenant des tests d'unité (Xunit) pouvant exécuter toutes les constructions. Jusqu'ici tout va bien.
Je souhaite également ajouter des tests d'intégration, qui ne seront pas exécutés sur toutes les constructions mais peuvent exécuter sur demande. Où mettez-vous ceux-ci et comment séparez-vous des tests unitaires des tests d'intégration? Si c'est dans la même solution avec les mêmes attributs [faits], il fonctionnera exactement de la même manière.
Quelle est l'approche préférée? Un deuxième projet de test distinct pour les tests d'intégration?
La séparation n'est pas un test d'unité par rapport à l'intégration. La séparation est rapide par rapport aux tests lents.
Comment organiserez-vous ces tests pour les rendre plus faciles à courir est vraiment à vous. Les dossiers séparés sont un bon départ, mais d'autres annotations comme des traits ou [Fact]
peut fonctionner aussi bien.
Je pense qu'il y a une idée fausse fondamentale ici sur ce qui constitue un test d'intégration et un test unitaire. Le début de la réponse de Flater vous donne les différences entre les deux (et oui, malheureusement, je vais citer une réponse déjà sur cette question)
flater dit:
La différence entre les tests d'unité et les tests d'intégration est qu'ils testent différentes choses. Très simplement mettre:
- Tests unitaires Test si une chose fait ce qu'elle est censée faire. ("Tommy peut-il jeter une balle?" Ou "Timmy attrape-t-il une balle?")
- Test d'intégration Test si deux (ou plus) choses peuvent travailler ensemble. ("Tommy peut-il jeter une balle à Timmy?")
Et une littérature de soutien de Martin Fowler:
Les tests d'intégration Déterminent si les unités de logiciels développées indépendamment fonctionnent correctement lorsqu'elles sont connectées les unes aux autres. Le terme est devenu floue même par les normes diffuses du logiciel L'industrie, donc j'ai été méfiante de l'utiliser dans mon écriture. En particulier, de nombreuses personnes assument des tests d'intégration sont nécessairement larges de portée, tandis que , ils peuvent être effectués plus efficacement avec une portée plus étroite .
(emphase, mien). Plus tard, il élabore des tests d'intégration:
Le test d'intégration, comme le nom l'indique, est de tester si de nombreux modules développés séparément fonctionnent ensemble comme prévu .
(l'emphase, son)
En ce qui concerne la "portée plus étroite" des tests d'intégration:
Le problème est que nous avons (au moins) deux notions différentes de ce qui constitue un test d'intégration.
tests d'intégration étroite
- exercer uniquement cette partie du code dans mon service qui parle à un service séparé
- utilise des tests doubles de ces services, en cours ou à distance
- se compose ainsi de nombreux tests étroitement scopés, souvent de portée plus importante qu'un test d'unité (et fonctionnent généralement avec le même cadre de test utilisé pour les tests d'unités)
tests d'intégration larges
- nécessite des versions en direct de tous les services, nécessitant un environnement de test substantiel et un accès réseau
- code de l'exercice des chemins de codes via tous les services, pas seulement le code responsable des interactions
(emphase, mien)
Maintenant, nous commençons à arriver à la racine du problème: Un test d'intégration peut exécuter rapidement ou lentement .
Si les tests d'intégration exécutent rapidement, alors les exécutez toujours chaque fois que vous exécutez des tests d'unité.
Si les tests d'intégration s'exécutent lentement, car ils doivent interagir avec des ressources extérieures telles que le système de fichiers, les bases de données ou les services Web, alors celles-ci doivent être exécutées lors d'une construction d'intégration continue et exécutées par des développeurs sur commande. Par exemple, juste avant la révision du code exécutant tous les tests (unité, intégration ou autre) qui s'appliquent au code que vous avez modifié.
C'est le meilleur équilibre entre le temps du développeur et trouver des défauts tôt dans le cycle de vie de développement.
La différence entre les tests d'unité et les tests d'intégration est qu'ils testent différentes choses. Très simplement mettre:
L'exemple de test d'intégration que j'ai donné peut sembler si simple qu'il ne vaut pas la peine d'être testé après avoir effectué l'exemple des tests unitaires; Mais gardez à l'esprit que j'ai trop simplifié cela pour des raisons d'explication.
tests d'intégration, qui ne seront pas exécutés sur toutes les constructions mais peuvent exécuter sur demande
Ce n'est pas vraiment comment vous êtes censé approcher des tests d'intégration. Ils sont tout aussi essentiels que des tests unitaires et doivent être exécutés sur le même calendrier.
Vous devez penser aux tests de l'unité et d'intégration sous forme de deux morceaux de "Test du package", et c'est ce paquet que vous devez exécuter lors du test. Cela n'a aucun sens de ne pas tester que moitié de l'objectif de votre application et considérez qu'un test de manière significative concluante.
Sans ajouter des tests d'intégration à votre horaire de test général, vous ignorez simplement les défaillances de test qui apparaîtraient. Des tests existent spécifiquement parce que vous souhaitez être alerté de leurs échecs, alors pourquoi voudriez-vous masquer intentionnellement ces alertes? C'est l'équivalent de tourner à la radio puis de coller vos doigts dans vos oreilles.
et comment séparez-vous des tests d'unité des tests d'intégration?
Bien qu'ils soient couramment séparés dans différents projets (généralement de la même solution), ce n'est pas une exigence technique, mais plutôt une façon de structurer le codeBase.
Si c'est dans la même solution avec les mêmes attributs [faits], il fonctionnera exactement de la même manière.
Comme je l'ai mentionné, les exécuter exactement de la même manière est ce que vous êtes censé faire.
Je suppose que vous voulez dire "dans le même projet" et non "dans la même solution". Ils sont souvent séparés en projets distincts dans la structuration du codeBase, mais aucune exigence technique ne vous obligeait à séparer les tests d'unité et d'intégration. Vous pouvez aussi bien les mettre dans le même projet, ce qui serait logique pour les petites codesbases avec seulement une poignée de tests.
Il n'y a pas d'approche "une taille unique convient à toutes".
Certains magasins les ont dans le même projet que les tests unitaires, d'autres préfèrent les avoir dans un projet séparé par eux-mêmes.
Cependant, vous le faites, je vous recommanderais de les signaler en tant que tel afin que le serveur de construction (en supposant que vous en avez un) puisse être défini pour exécuter un sous-ensemble de tests car le gestionnaire de construction et/ou les développeurs jugent en forme.
Je ne suis pas au fait avec Xunit pour être honnête, mais il semble que cela puisse être fait par trait .
Une fois qu'ils sont en place, les développeurs peuvent ensuite choisir les catégories de tests qu'ils souhaitent courir localement, ce qui peut accélérer le développement.
Cela dépend probablement du cadre de test (vous utilisez un, non?)
Pour Junit 4/5, nous avons des suites de test séparées.
Nous exécutons un ensemble localement, une autre avant les demandes de tirage du niveau de groupe (tests unitaires pour tous les bocaux). Les tests d'intégration 126K, qui peuvent prendre plusieurs heures à exécuter (extrémités/tests d'intégration à l'aide de SELENIUM, Weblogic, Oracle RDBMS et Oracle BI Publisher, Docker, Bunch d'autres lits de 3e parties) sont exécutés avant la publication des demandes de tirage et celles-ci courir toutes les 6 heures.
Au besoin, bien sûr, nous pouvons également exécuter les tests localement, mais il est douloureux en raison de la durée et de la configuration spéciale nécessaire aux images Docker locales, nous attendons donc en général comment les serveurs de groupe de groupe le gèrent.
Il n'y a probablement pas de réponse "correcte", mais j'ai quelques règles simples de pouce, ce qui fonctionne bien pour moi:
Les tests doivent vérifier si les exigences de l'entreprise (cas d'utilisation) sont remplies. Cela signifie qu'il n'y a pas de composant simple ou compliqué à tester, il n'est qu'une exigence, ce qui est la seule raison d'ajouter un nouveau test.
Seules les API sont testées, jamais la mise en œuvre.
Les moqueurs doivent être évités au minimum (uniquement pour des ressources très lentes ou coûteuses).
Les tests d'unités peuvent être exécutés sur le niveau de code sans être déployés.
Les tests d'intégration valident un composant sont correctement intégrés dans le système. Cela signifie que le composant doit être déployé.
Cette différence, déployée ou non, détermine la place dans votre processus de déploiement (étape de pipeline).