Quelle est la différence entre l'intégration et les tests unitaires?

je connais la soi-disant définition classique des tests unitaires et des tests d'intégration. Ce qui m'intéresse, c'est quand il est temps d'écrire des tests unitaires... Je vais les écrire pour couvrir autant de séries de classes que possible.

par exemple, si j'ai une classe Word , je vais écrire quelques tests unitaires pour la classe Word . Puis, je commence à écrire ma classe Sentence , et quand il a besoin d'interagir avec la classe Word , je vais souvent écrire mes tests unitaires tels qu'ils testent à la fois Sentence et Word ... au moins dans les endroits où ils interagissent.

ces tests sont-ils essentiellement devenus des tests d'intégration parce qu'ils testent maintenant l'intégration de ces deux classes, ou s'agit-il simplement d'un test unitaire qui couvre deux classes?

en général, en raison de cette ligne incertaine, je vais rarement réellement écrire des tests d'intégration... ou est-ce que j'utilise le produit fini pour voir si tous les les pièces fonctionnent correctement les tests d'intégration réels, même s'ils sont manuels et rarement répétés au-delà de la portée de chaque caractéristique individuelle?

est-ce que je ne comprends pas les tests d'intégration, ou y a-t-il vraiment très peu de différence entre les tests d'intégration et les tests unitaires?


Modifier

Merci pour toutes les bonnes réponses tout le monde! Je pense que d'après les réponses variées il est clair que la ligne entre les tests unitaires et d'intégration sont certainement une ligne floue, et c'est peut-être un peu pédant d'essayer de trouver quels sont ceux qui devraient rester sur le code (merci @Rob Cooper). Aussi, désolé mais je ne vais accepter aucune réponse parce que trop sont trop bons, et il semble vraiment très subjectif.

262
demandé sur nbro 2008-08-14 10:27:57

19 réponses

la différence clé, pour moi, est que tests d'intégration révèlent si une caractéristique fonctionne ou est cassée, car ils soulignent le code dans un scénario proche de la réalité. Ils font appel à une ou plusieurs méthodes ou fonctionnalités logicielles et testent si elles agissent comme prévu.

au contraire, un test unitaire tester une seule méthode repose sur l'hypothèse (souvent fausse) que le reste du logiciel fonctionne correctement, parce qu'il se moque explicitement de chaque dépendance.

par conséquent, lorsqu'un essai unitaire pour une méthode mettant en œuvre une caractéristique est vert, il ne pas signifie que la caractéristique fonctionne.

dites que vous avez une méthode quelque part comme ça:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  Log.TrackTheFactYouDidYourJob();
  return someResults;
}

DoSomething est très important pour votre client: c'est une fonctionnalité, la seule chose qui compte. C'est pourquoi vous écrivez habituellement une spécification de concombre affirmant: vous souhaitez vérifier et communiquer la fonctionnalité fonctionne ou pas.

Feature: To be able to do something
  In order to do something
  As someone
  I want the system to do this thing

Scenario: A sample one
  Given this situation
  When I do something
  Then what I get is what I was expecting for

sans doute: si le test est réussi, vous pouvez affirmer que vous livrez une fonctionnalité de travail. C'est ce que vous pouvez appeler valeur D'entreprise .

si vous voulez écrire un test unitaire pour DoSomething vous devriez prétendre (en utilisant quelques moqueries) que le reste des classes et des méthodes fonctionnent (c'est-à-dire: que, tous les dépendances que la méthode utilise fonctionnent correctement) et affirment que votre méthode fonctionne.

dans la pratique, vous faites quelque chose comme:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
  return someResults;
}

vous pouvez faire cela avec L'Injection de dépendance, ou une méthode D'usine ou n'importe quel cadre simulé ou tout simplement étendre la classe sous test.

supposons qu'il y ait un bug dans Log.DoSomething() . Heureusement, la spectroscopie Gherkin le trouvera et vos tests de bout en bout échoueront.

la fonctionnalité ne fonctionnera pas, parce que Log est cassé, pas parce que [Do your job with someInput] ne fait pas son travail. Et, soit dit en passant, [Do your job with someInput] est l'unique responsable de cette méthode.

aussi, supposons que Log soit utilisé dans 100 autres caractéristiques, dans 100 autres méthodes de 100 autres classes.

Yep, 100 fonctionnalités échouent. Mais, heureusement, 100 tests de bout en bout échouent également et révèlent le problème. Et, oui: ils disent la vérité .

c'est une information très utile: je sais que j'ai un produit cassé. C'est aussi une information très confuse: elle ne me dit rien sur l'endroit où se trouve le problème. Il communique moi le symptôme, pas la cause.

encore, DoSomething l 'unité test est vert , parce qu'il utilise un faux Log , construit pour ne jamais casser. Et, oui: c'est clairement mens . C'est communiquer une caractéristique brisée est travailler. Comment peut-il être utile?

(si le test de l'Unité de DoSomething() échoue, assurez-vous: [Do your job with someInput] a quelques bugs.)

supposons que ce soit un système avec une classe cassée: A system with a broken class

un seul bug cassera plusieurs fonctionnalités, et plusieurs tests d'intégration échoueront.

A single bug will break several features, and several integration tests will fail

d'un autre côté, le même bug ne cassera qu'une unité test.

The same bug will break just one unit test

maintenant, comparez les deux scénarios.

le même bug ne cassera qu'un test unitaire.

  • toutes vos fonctionnalités en utilisant le Log sont en rouge
  • tous vos tests unitaires sont verts, seul le test unitaire pour Log est Rouge

" en fait, des essais unitaires pour tous les modules utilisant un les fonctionnalités sont vertes car, en utilisant mocks, elles suppriment les dépendances. En d'autres termes, ils fonctionnent dans un monde idéal, complètement fictif. Et c'est la seule façon d'isoler les insectes et de les chercher. Le test de l'unité signifie se moquer. Si tu ne te moques pas, tu ne testes pas à l'unité.

la différence

les tests D'intégration disent quoi ne fonctionne pas. Mais ils ne sont d'aucune utilité dans deviner où le problème pourrait être.

les tests unitaires sont les seuls tests qui vous indiquent se trouve exactement le bogue. Pour dessiner cette information, ils doivent exécuter la méthode dans un environnement moqué, où toutes les autres dépendances sont supposées fonctionner correctement.

C'est pourquoi je pense que votre phrase "Ou est-ce juste un test unitaire qui s'étend sur 2 classes" est en quelque sorte déplacées. Un test unitaire ne devrait jamais couvrir deux classes.

cette réponse est essentiellement un résumé de ce que j'ai écrit ici: Unité tests mensonge, c'est pourquoi je les aime .

258
répondu Arialdo Martini 2018-05-10 12:07:34

quand j'écris des tests unitaires, je limite la portée du code testé à la classe que j'écris actuellement en me moquant des dépendances. Si j'écris une classe de phrases, et que la phrase dépend de Word, j'utiliserai un mot fictif. En moquant Word, Je ne peux me concentrer que sur son interface et tester les différents comportements de ma classe de phrases alors qu'elle interagit avec L'interface de Word. De cette façon, je ne teste que le comportement et la mise en œuvre de la phrase et pas en même temps tester le mise en œuvre de Word.

une fois que j'ai écrit les tests unitaires pour m'assurer que la phrase se comporte correctement lorsqu'elle interagit avec Word basé sur L'interface de Word, alors j'écris le test d'intégration pour m'assurer que mes hypothèses au sujet des interactions étaient correctes. Pour cela je fournis les objets réels et écris un test qui exerce une fonctionnalité qui finira par utiliser à la fois la phrase et le mot.

57
répondu Larry Foulkrod 2018-04-16 20:15:33

mes 10 bits: d

on m'a toujours dit que Tests Unitaires est l'essai d'un composant individuel - qui devrait être exercé à son maximum. Maintenant, cela tend à avoir de nombreux niveaux, puisque la plupart des composants sont constitués de pièces plus petites. Pour moi, un unité est une partie fonctionnelle du système. Donc il doit fournir quelque chose de valeur (c.-à-d. pas une méthode pour l'analyse de chaîne, mais un HtmlSanitizer peut-être).

Integration Tests est la prochaine étape, qui consiste à prendre un ou plusieurs composants et à s'assurer qu'ils fonctionnent ensemble comme ils le devraient.. Vous êtes alors au-dessus des complexités de l'inquiétude sur comment les composants fonctionnent individuellement, mais quand vous entrez html dans votre HtmlEditControl , il sait de façon magique si son valide ou non..

C'est un vrai mobile ligne.. Je préférerais me concentrer davantage sur le fait que ce fichu code fonctionne à fond. 151910920"

41
répondu Rob Cooper 2008-08-14 08:59:28

tests Unitaires mocker

ce dont vous parlez, ce sont des tests d'intégration qui testent en fait toute l'intégration de votre système. Mais quand vous faites le test d'unité vous devriez réellement tester chaque unité séparément. Tout le reste devrait être moqué. Donc dans votre cas de la classe Sentence , si elle utilise la classe Word , alors votre classe Word devrait être moquée. De cette façon, vous ne testerez que la fonctionnalité de votre classe Sentence .

18
répondu Robert Koritnik 2012-04-20 08:06:11

je pense que lorsque vous commencez à penser aux tests d'intégration, vous parlez davantage d'un croisement entre des couches physiques que des couches logiques.

par exemple, si vos tests concernent la génération de contenu, c'est un test unitaire: si votre test concerne uniquement l'écriture sur disque, c'est toujours un test unitaire, mais une fois que vous testez à la fois l'entrée/sortie et le contenu du fichier, alors vous avez vous-même un test d'intégration. Lorsque vous testez la sortie d'une fonction un service, c'est un test unitaire, mais une fois que vous faites un appel de service et voyez si le résultat de la fonction est le même, alors c'est un test d'intégration.

techniquement, vous ne pouvez pas tester une seule classe de toute façon. Que faire si votre classe est composée avec plusieurs autres classes? Le fait automatiquement faire un test d'intégration? Je ne le pense pas.

16
répondu Jon Limjap 2008-08-14 06:34:05

test unitaire: test effectué sur une unité ou sur un plus petit logiciel. Fait pour vérifier si elle satisfait à sa spécification fonctionnelle ou à la structure de conception prévue.

les Tests d'Intégration: Tester les modules ensemble de ses fonctionnalités.

11
répondu krishna 2013-12-13 10:55:49

utilisant un design à responsabilité unique, en noir et blanc. Plus d'une responsabilité, c'est un test d'intégration.

par le test duck (looks, charlatans, waddles, its a duck), c'est juste un test unitaire avec plus d'un Objet neuf en elle.

lorsque vous entrez dans mvc et que vous le testez, les tests du contrôleur sont toujours une intégration, car le contrôleur contient à la fois une unité de modèle et une unité de vue. Tester la logique dans ce modèle, je dirais un test unitaire.

10
répondu DevelopingChris 2008-08-14 06:36:29

À mon avis, la réponse est "Pourquoi est-il important?"

est-ce parce que les tests unitaires sont quelque chose que vous faites et les tests d'intégration sont quelque chose que vous ne faites pas? Ou vice-versa? Bien sûr que non, vous devriez essayer de faire les deux.

est-ce parce que les tests unitaires doivent être rapides, isolés, reproductibles, Auto-validables et opportuns et que les tests d'intégration ne devraient pas l'être? Bien sûr que non, tous les tests doivent être présentes.

c'est parce que vous utilisez des moqueries dans l'unité des tests, mais vous ne les utilisez pas dans les tests d'intégration? Bien sûr que non. Cela impliquerait que si j'ai une utile d'essai d'intégration, je ne suis pas autorisé à ajouter une maquette pour une partie, de peur que j'ai renommer mon test "test unitaire" ou les remettre à un autre programmeur de travailler sur.

est-ce parce que les tests unitaires testent une unité et les tests d'intégration testent un certain nombre d'unités? Bien sûr que non. De quelle importance pratique s'agit-il? La discussion théorique sur la portée des essais se décompose dans la pratique, en tout cas, parce que le terme "unité" dépend entièrement du contexte. Au niveau de la classe, une unité pourrait être une méthode. Au niveau de l'assemblée, une unité peut être une classe, et au niveau du service, une unité peut être un composant. Et même les classes utilisent d'autres classes, alors quelle est l'unité?

cela n'a aucune importance.

L'essai est important, F. I. R. S. T est important, séparer les cheveux sur les définitions est une perte de temps qui confond seulement les nouveaux venus à l'essai.

8
répondu David Sackstein 2015-08-28 20:04:28

pensez à la nature de vos tests dans les termes suivants:

  • réduction des risques : c'est à ça que servent les tests. Seule une combinaison de tests unitaires et de tests d'intégration peut vous donner une réduction complète du risque, parce que les tests unitaires ne peuvent pas tester l'interaction appropriée entre les modules et les tests d'intégration peuvent exercer la fonctionnalité d'un module non trivial que dans une faible mesure.
  • effort d'écriture de Test : les tests D'intégration peuvent économiser de l'effort parce que vous n'avez pas besoin d'écrire stubs/fakes/Mock. Mais les tests unitaires peuvent également vous épargner des efforts lors de la mise en oeuvre (et du maintien! il se trouve que ces stubs/fakes/mocks sont plus faciles que de configurer la configuration du test sans eux.
  • délai d'exécution des tests : les tests D'intégration impliquant des opérations lourdes (telles que l'accès à des systèmes externes tels que les serveurs DBs ou distants) tendent à pour être lent. Cela signifie que les tests unitaires peuvent être exécutés beaucoup plus fréquemment, ce qui réduit l'effort de débogage si quelque chose échoue, parce que vous avez une meilleure idée de ce que vous avez changé dans l'intervalle. Cela devient particulièrement important si vous utilisez le développement piloté par les tests (TDD).
  • effort de débogage : si un test d'intégration échoue, mais aucun des tests unitaires ne le fait, cela peut être très gênant, car il y a tellement de code impliqué que peut contiennent le problème. Ce n'est pas un gros problème si vous avez déjà changé seulement quelques lignes -- mais comme les tests d'intégration fonctionnent lentement, vous avez peut-être fait pas les exécuter dans des intervalles si courts...

rappelez-vous qu'un test d'intégration peut encore esquiver/simuler/truquer une partie de ses dépendances. Cela fournit beaucoup de terrain d'entente entre les essais unitaires et les essais de système (l'intégration la plus complète tests, essais de tout le système).

une approche pragmatique consisterait donc à: S'appuyer avec souplesse sur les tests d'intégration autant que l'on peut raisonnablement le faire et utiliser des tests unitaires là où cela serait trop risqué ou incommode. Cette façon de penser peut être plus utile que certaines discriminations dogmatiques des tests unitaires et des tests d'intégration.

8
répondu Lutz Prechelt 2018-03-19 12:49:47

je pense que j'appellerais encore quelques classes en interaction un test unitaire à condition que les tests unitaires pour la classe 1 testent les caractéristiques de la classe 1, et que les tests unitaires pour la classe 2 testent ses caractéristiques, et aussi qu'ils ne frappent pas la base de données.

j'appelle un test un test d'intégration quand il parcourt la majeure partie de ma pile et atteint même la base de données.

j'aime vraiment cette question, parce que la discussion TDD se sent parfois un peu trop puriste pour moi, et c'est bon pour moi de voir des exemples concrets.

3
répondu Lance Fisher 2008-08-14 06:37:17

je fais la même chose - je les appelle tous les tests unitaires, mais à un certain moment, j'ai un "test unitaire" qui couvre tellement je l'ai souvent le renommer en "..IntegrationTest" - juste un changement de nom seulement, rien d'autre ne change.

je pense qu'il y a une suite de "tests atomiques" (tester une classe minuscule, ou une méthode) à des tests unitaires (niveau de la classe) et des tests d'intégration - et puis test fonctionnel (qui couvrent normalement beaucoup plus de choses du haut vers le bas) - il ne semble pas y avoir nettoyer les couper.

si votre test met en place des données, et peut-être charge une base de données/fichier, etc, alors peut-être son plus d'un test d'intégration (tests d'intégration je trouve utiliser moins de moqueries et plus de classes réelles, mais cela ne signifie pas que vous ne pouvez pas vous moquer d'une partie du système).

3
répondu Michael Neale 2008-08-14 06:47:54

Unit Testing est une méthode d'essai qui vérifie que les unités individuelles du code source fonctionnent correctement.

Test d'Intégration est la phase de tests de logiciels dans lequel les différents modules du logiciel sont combinés et testé en tant que groupe.

Wikipedia définit une unité comme la plus petite partie testable d'une application, qui en Java/c# est une méthode. Mais dans votre exemple de classe de mots et de phrases j'écrirais probablement juste les tests pour la phrase car je trouverais probablement exagéré d'utiliser une classe de mots mock afin de tester la classe de phrase. Donc, la phrase serait mon unité et word est un détail de l'implémentation de cette unité.

3
répondu grom 2008-08-14 10:26:18

les tests d'Intégration: Base de données de persistance est testé.

Tests unitaires: l'accès à la base de données est moqué. Code de méthodes sont testées.

3
répondu Pascal 2012-07-18 17:01:22
"151900920 de tests Unitaires, tests à l'encontre d'une unité de travail ou d'un bloc de code si vous le souhaitez. Généralement effectuée par un seul développeur.

les tests d'Intégration renvoie à l'examen qui est effectué, de préférence sur un serveur d'intégration, lorsqu'un développeur que leur code source du référentiel de contrôle. Les essais d'intégration pourraient être effectués par des services publics tels que le régulateur de vitesse.

Si vous faites vos tests unitaires pour valider que l'unité de travail que vous avez construit fonctionne et le test d'intégration valide que tout ce que vous avez ajouté au dépôt n'a pas cassé autre chose.

2
répondu Christian Hagelid 2008-08-14 06:36:58

un peu académique cette question, n'est-ce pas? ;-) De mon point de vue: Pour moi un test d'intégration, test de l'ensemble de la partie, pas si les deux parties sur dix vont ensemble. Notre test d'intégration montre, si le Master build (contenant 40 projets) réussira. Pour les projets, nous avons des tonnes de tests unitaires. La chose la plus importante concernant les tests unitaires pour moi est qu'un test unitaire ne doit pas dépendre d'un autre test unitaire. Donc pour moi les deux test vous décrivez ci-dessus sont des tests unitaires, si elles sont indépendantes. Pour les tests d'intégration, cela n'a pas besoin d'être important.

1
répondu John Smithers 2008-08-14 06:37:59

j'appelle les tests unitaires de ces tests boîte blanche de test d'une classe. Toutes les dépendances dont la classe a besoin sont remplacées par des fausses (moqueries).

les tests D'intégration sont les tests où plusieurs classes et leurs interactions sont testées en même temps. Seules quelques dépendances dans ces cas sont truquées.

Je n'appellerai pas les tests d'intégration du contrôleur à moins qu'une de leurs dépendances ne soit réelle (c'est-à-dire non falsifiée) (par ex. IFormsAuthentication).

séparer les deux types d'essais est utile pour tester le système à différents niveaux. Aussi, les tests d'intégration ont tendance à être de longue durée, et les tests unitaires sont censés être rapide. La distinction de vitesse d'exécution signifie qu'ils sont exécutés différemment. Dans nos processus de développement, les tests unitaires sont effectués au check-in (ce qui est bien car ils sont super rapides), et les tests d'intégration sont effectués une/deux fois par jour. J'essaie de faire des tests d'intégration aussi souvent que possible, mais habituellement frapper la base de données/écrire aux dossiers/faire des rpc/etc ralentit.

qui soulève un autre point important, les tests unitaires devraient éviter de frapper IO (par exemple disque, réseau, db). Sinon, ils ralentissent beaucoup. Je ne peux pas admettre que j'ai été fidèle à la règle "les tests unitaires doivent être rapides", mais si vous l'êtes, les avantages d'un système beaucoup plus grand deviennent apparents très rapidement.

1
répondu CVertex 2008-08-14 12:19:55

les exemples ci-dessus font très bien et je n'ai pas besoin de les répéter. Je vais donc me concentrer sur l'utilisation d'exemples pour vous aider à comprendre.

Essais D'Intégration

les tests D'intégration vérifient si tout fonctionne bien. Imaginez une série de rouages travaillant ensemble dans une montre. Un test d'intégration serait: est la montre de raconter le bon moment? Est-ce toujours l'heure exacte en 3 jours?

Tout ce qu'il dit vous êtes si l'ensemble de la pièce fonctionne. Si elle échoue: elle ne vous dit pas exactement où elle échoue.

Tests Unitaires

ce sont vraiment des types spécifiques de test. Ils vous disent si une chose spécifique fonctionne ou échoue. La clé de ce type de test est qu'il ne teste qu'une chose spécifique tout en supposant que tout le reste fonctionne très bien. C'est le point clé.

Exemple: Nous allons développer sur ce point en utilisant un exemple:

  • prenons l'exemple d'une voiture.
  • Integration test pour une voiture: par exemple, la voiture conduit-elle à Echuca et vice-versa. Si elle le fait, vous pouvez dire sans risque qu'une voiture fonctionne d'un point de vue global. C'est un test d'intégration. S'il échoue, vous n'avez aucune idée de l'endroit où il tombe: est-ce le radiateur, la transmission, le moteur ou le carburateur? Vous n'avez aucune idée. Il pourrait être n'importe quoi.
  • test Unitaire pour une voiture: le moteur fonctionne. Ce test suppose que tout le reste de la voiture fonctionne très bien. De cette façon, si le test de cette unité particulière échoue: vous pouvez être très sûr que le problème réside dans le moteur – de sorte que vous pouvez rapidement isoler et corriger le problème.

Les conséquences de mixage de votre intégration et les tests unitaires:

  • supposons que votre test d'intégration de voiture échoue. Il ne conduit pas avec succès à Echuca. Où est le problème?

  • Vous regardez dans votre moteur de test. Mais dans ce cas précis, le test moteur utilise des dépendances externes: il utilise un système de carburant spécial. Supposons que le test du groupe moteur ait également échoué. En d'autres termes, le test d'intégration et le test du groupe moteur ont échoué. Où est l' problème? (Donnez-vous 10 secondes pour obtenir la réponse.) • Le moteur est-il tombé en panne ou est-ce le circuit carburant qui a causé la panne?

Vous voyez le problème? Vous ne savez pas ce qu'est exactement un échec. Si vous utilisez 10 dépendances, puis chacun de ces 10 pourrait avoir causé le problème – et vous ne savez pas par où commencer. C'est pourquoi unit teste les moqueries pour supposer que tout le reste fonctionne très bien.

I espérons que cette aide.

1
répondu BKSpurgeon 2018-03-14 23:50:36

ces tests sont-ils essentiellement devenus des tests d'intégration parce qu'ils testent maintenant l'intégration de ces 2 classes? Ou est-ce juste un test unitaire qui s'étend sur 2 classes?

je pense que oui et oui. Votre test d'unité qui s'étend sur 2 classes est devenu un test d'intégration.

vous pourriez l'éviter en testant la classe de Phrase Avec l'implémentation simulée-Classe MockWord, ce qui est important quand ces parties du système sont assez grandes pour être mis en œuvre par différents développeurs. Dans ce cas, Word est testé en unité seule, Sentence est testé en unité à l'aide de MockWord, puis Sentence est testé en intégration avec Word.

exemple de différence réelle peut être suivante 1) Tableau de 1 000 000 d'éléments est facilement unité testé et fonctionne très bien. 2) BubbleSort est facilement testé à l'unité sur une maquette de 10 éléments et fonctionne aussi bien 3) Les tests D'intégration montrent que quelque chose ne va pas si bien.

si ces les pièces sont développées par une seule personne, le plus probable problème sera trouvé tandis que L'Unité de test BubbleSoft tout simplement parce que le développeur a déjà réel tableau et il n'a pas besoin de simulation de mise en œuvre.

0
répondu Pavel Feldman 2008-09-25 09:37:29

en outre, il est important de se rappeler que les tests unitaires et les tests d'intégration peuvent être automatisés et écrits en utilisant, par exemple, JUnit. Dans les tests D'intégration de JUnit, on peut utiliser la classe org.junit.Assume pour tester la disponibilité des éléments d'environnement (par exemple, connexion à une base de données) ou d'autres conditions.

0
répondu Paulo Merson 2013-09-10 17:12:33