Quelle est la différence entre les tests unitaires, fonctionnels, d'acceptation et d'intégration? [fermé]

799

Quelle est la différence entre les tests unitaires, fonctionnels, d'acceptation et d'intégration (et tous les autres types de tests que j'ai omis de mentionner)?

Andrew
la source
1
Voir aussi sqa.stackexchange.com/a/23396/8992
Michael Durrant
1
Je pense que vous avez oublié d'inclure les tests de charge!
Talk is Cheap Montrez-moi le code

Réponses:

1350

Selon l'endroit où vous regardez, vous obtiendrez des réponses légèrement différentes. J'ai beaucoup lu sur le sujet, et voici ma distillation; encore une fois, ils sont légèrement laineux et d'autres peuvent être en désaccord.

Tests unitaires

Teste la plus petite unité de fonctionnalité, généralement une méthode / fonction (par exemple, étant donné une classe avec un état particulier, l'appel de la méthode x sur la classe devrait provoquer y). Les tests unitaires devraient être axés sur une caractéristique particulière (par exemple, appeler la méthode pop lorsque la pile est vide devrait lancer un InvalidOperationException). Tout ce qu'il touche doit être fait en mémoire; cela signifie que le code de test et le code sous test ne doivent pas:

  • Appelez des collaborateurs (non triviaux)
  • Accéder au réseau
  • Frappez une base de données
  • Utiliser le système de fichiers
  • Faites tourner un fil
  • etc.

Tout type de dépendance lente / difficile à comprendre / initialiser / manipuler doit être tronqué / moqué / peu importe en utilisant les techniques appropriées afin que vous puissiez vous concentrer sur ce que fait l'unité de code, pas sur ce que font ses dépendances.

En bref, les tests unitaires sont aussi simples que possible, faciles à déboguer, fiables (en raison de facteurs externes réduits), rapides à exécuter et aident à prouver que les plus petits blocs de construction de votre programme fonctionnent comme prévu avant d'être assemblés. La mise en garde est que, bien que vous puissiez prouver qu'elles fonctionnent parfaitement isolément, les unités de code peuvent exploser lorsqu'elles sont combinées, ce qui nous amène à ...

Tests d'intégration

Les tests d'intégration s'appuient sur des tests unitaires en combinant les unités de code et en vérifiant que la combinaison résultante fonctionne correctement. Cela peut être soit les entrailles d'un système, soit la combinaison de plusieurs systèmes pour faire quelque chose d'utile. En outre, l'environnement différencie les tests d'intégration des tests unitaires. Les tests d'intégration peuvent utiliser et utiliseront des threads, accéderont à la base de données ou feront tout ce qui est nécessaire pour garantir que tout le code et les différentes modifications d'environnement fonctionneront correctement.

Si vous avez construit du code de sérialisation et que l'unité a testé ses entrailles sans toucher au disque, comment savez-vous que cela fonctionnera lorsque vous chargerez et enregistrerez sur le disque? Vous avez peut-être oublié de rincer et d'éliminer les flux de fichiers. Peut-être que vos autorisations de fichiers sont incorrectes et que vous avez testé les entrailles à l'aide de flux de mémoire. La seule façon de le savoir avec certitude est de le tester «pour de vrai» en utilisant un environnement le plus proche de la production.

Le principal avantage est qu'ils trouveront des bogues que les tests unitaires ne peuvent pas tels que les bogues de câblage (par exemple, une instance de classe A reçoit de manière inattendue une instance nulle de B) et des bogues d'environnement (cela fonctionne bien sur ma machine à processeur unique, mais mon La machine à 4 cœurs de mon collègue ne peut pas passer les tests). Le principal inconvénient est que les tests d'intégration touchent plus de code, sont moins fiables, les échecs sont plus difficiles à diagnostiquer et les tests sont plus difficiles à maintenir.

De plus, les tests d'intégration ne prouvent pas nécessairement qu'une fonctionnalité complète fonctionne. L'utilisateur peut ne pas se soucier des détails internes de mes programmes, mais je le fais!

Tests fonctionnels

Les tests fonctionnels vérifient l'exactitude d'une caractéristique particulière en comparant les résultats d'une entrée donnée à la spécification. Les tests fonctionnels ne concernent pas les résultats intermédiaires ou les effets secondaires, juste le résultat (ils ne se soucient pas qu'après avoir fait x, l'objet y ait l'état z). Ils sont écrits pour tester une partie de la spécification telle que "la fonction d'appel Square (x) avec l'argument de 2 renvoie 4".

Tests d'acceptation

Les tests d'acceptation semblent être divisés en deux types:

Les tests d'acceptation standard impliquent d'effectuer des tests sur le système complet (par exemple, en utilisant votre page Web via un navigateur Web) pour voir si la fonctionnalité de l'application satisfait aux spécifications. Par exemple, "cliquer sur une icône de zoom devrait agrandir la vue du document de 25%". Il n'y a pas de véritable continuum de résultats, juste un résultat de réussite ou d'échec.

L'avantage est que les tests sont décrits en anglais simple et garantissent que le logiciel, dans son ensemble, est complet. L'inconvénient est que vous avez déplacé un autre niveau vers le haut de la pyramide de test. Les tests d'acceptation touchent des montagnes de code, donc la recherche d'un échec peut être délicate.

En outre, dans le développement de logiciels agiles, les tests d'acceptation des utilisateurs impliquent la création de tests pour refléter les histoires d'utilisateurs créées par / pour le client du logiciel pendant le développement. Si les tests réussissent, cela signifie que le logiciel doit répondre aux exigences du client et que les histoires peuvent être considérées comme complètes. Une suite de tests d'acceptation est essentiellement une spécification exécutable écrite dans un langage spécifique au domaine qui décrit les tests dans le langage utilisé par les utilisateurs du système.

Conclusion

Ils sont tous complémentaires. Parfois, il est avantageux de se concentrer sur un type ou de les éviter complètement. La principale différence pour moi est que certains des tests regardent les choses du point de vue d'un programmeur, tandis que d'autres utilisent une approche client / utilisateur final.

Mark Simpson
la source
19
+1. @Mark Simpson Les tests fonctionnels et d'acceptation peuvent-ils être résumés comme des "tests système"? Où se situent les tests de bout en bout? (vocabulaire trop différent à mon goût)
Torsten Engelbrecht
3
@Franz Je parlais de la capacité et de la facilité avec lesquelles vous pouvez réduire les risques en isolant des unités de code et en les testant. Vous avez cependant raison, le langage que j'ai utilisé était un peu lâche, car les tests ne peuvent pas prouver que le code est exempt de bogues.
Mark Simpson
15
Malgré les votes positifs, c'est complètement faux. Les tests unitaires ne testent même pas les collaborateurs "triviaux"; toute dépendance injectée doit être raillée. Les tests fonctionnels ne testent pas le «comportement»; ils testent uniquement la "fonction", c'est-à-dire que "f (A) renvoie B". Si les effets secondaires sont importants, c'est "comportementaux". S'il s'agit d'appels système, ce sont aussi des tests «système», comme dans les «tests système comportementaux». (Voir testerab @ ci-dessous.) Les tests "d'acceptation" sont un sous-ensemble de "tests du système comportemental" qui couvrent la pile complète. "Intégration" teste vers le haut, simulant une utilisation réelle; il teste que toutes les dépendances peuvent être intégrées dans la pratique.
cdunn2001
7
@ cdunn2001: Ne vous inquiétez pas, la critique constructive est toujours bonne :) Votre commentaire m'a appris quelques choses que je ne connaissais pas et a quelque peu nettoyé ma terminologie. J'ai toujours hâte d'apprendre de nouvelles choses auprès des développeurs qui aiment les tests. Je me souviens de la première fois que j'ai découvert le blog de Miško Hevery - c'était comme un trésor :)
Mark Simpson
11
@MarkSimpson bien que votre réponse soit très bonne, j'aimerais un peu plus de détails concernant les tests fonctionnels. Je veux dire dans votre réponse, pour moi, il est difficile de faire la distinction entre les tests fonctionnels et les tests unitaires. J'espère que vous avez le temps pour cela, continuez votre excellent travail!
Andrei Sandulescu
90

L'important est que vous sachiez ce que ces termes signifient pour vos collègues. Différents groupes auront des définitions légèrement différentes de ce qu'ils signifient lorsqu'ils disent des tests de "bout en bout", par exemple.

Je suis récemment tombé sur le système de nommage de Google pour leurs tests, et je l'aime plutôt - ils contournent les arguments en utilisant simplement Small, Medium et Large. Pour décider dans quelle catégorie un test s'inscrit, ils examinent quelques facteurs - combien de temps faut-il pour s'exécuter, accède-t-il au réseau, à la base de données, au système de fichiers, aux systèmes externes, etc.

http://googletesting.blogspot.com/2010/12/test-sizes.html

J'imagine que la différence entre Small, Medium et Large pour votre lieu de travail actuel pourrait différer de celle de Google.

Cependant, ce n'est pas seulement une question de portée, mais de but. Le point de Mark sur les différentes perspectives pour les tests, par exemple programmeur vs client / utilisateur final, est vraiment important.

testerab
la source
6
+1 pour la dénomination du test Google, car cela permet de comprendre pourquoi diverses organisations / personnes ont des définitions différentes pour les tests.
Mark Simpson
C'est également un très bon article expliquant pourquoi vous utilisez différents niveaux de test et ce que vous en retirez
testerab
63

http://martinfowler.com/articles/microservice-testing/

Le billet de blog de Martin Fowler parle de stratégies pour tester le code (en particulier dans une architecture de micro-services) mais la plupart s'applique à n'importe quelle application.

Je citerai sa diapositive récapitulative:

  • Tests unitaires - testez les plus petits logiciels testables de l'application pour déterminer s'ils se comportent comme prévu.
  • Tests d'intégration - vérifiez les voies de communication et les interactions entre les composants pour détecter les défauts d'interface.
  • Tests de composants - limitez la portée du logiciel utilisé à une partie du système testé, en manipulant le système via des interfaces de code internes et en utilisant des doublons de test pour isoler le code testé des autres composants.
  • Tests de contrat - vérifier les interactions à la frontière d'un service externe en affirmant qu'il répond au contrat attendu par un service consommateur.
  • Tests de bout en bout - vérifiez qu'un système répond aux exigences externes et atteint ses objectifs, testant l'ensemble du système de bout en bout.
Maxime
la source
C'est un excellent article d'ailleurs. Cependant, je ne comprends pas complètement à quoi servent les tests de contrat. Ne sont-ils pas redondants à la lumière des tests de composants et d'intégration?
wheleph
Dans certaines langues (que M. Fowler utilise), vous pouvez implémenter une interface qui n'est pas exposée lors de l'utilisation de la définition standard d'une classe, par exemple void IMyInterface.MyMethod (). Qui à son tour aurait logiquement ses propres tests. Bien qu'à ce moment-là, vous vous dirigez vers BDD .. Ironiquement, M. Fowler a également eu une prise de terre.
Skarsnik
2
ce n'est pas l'article Fowler btw, juste posté là-bas. Les tests de contrat sont des tests qui sont effectués après que les clients commencent à utiliser votre service, vous écrivez ensuite des tests qui vérifient si vous n'avez pas cassé quelque chose pour ces clients particuliers, c'est-à-dire changer l'api du service.
Rafał Łużyński
Les tests unitaires, d'intégration et de composants @wheleph parlent principalement pour les logiciels internes qui sont fortement contrôlables par le développeur. Un problème dans les trois premiers signifie que vous changez votre source pour résoudre le problème. - Les tests de contrat touchent à ce qui vous est promis en termes de fonctionnalité mais vous ne pourrez peut-être pas changer directement en cas de défaut. Cela nécessite l'ajout de code de support pour contourner ces problèmes possibles au lieu de simplement corriger le défaut. - Donc, vous travailleriez autour d'un service Web qui vous rendrait un fichier json mal formé même si les spécifications du contrat vous indiquaient qu'il s'agissait d'une certaine structure.
Yemi Bedu
31

Test unitaire - Comme son nom l'indique, cette méthode teste au niveau de l'objet. Les composants logiciels individuels sont testés pour détecter toute erreur. La connaissance du programme est nécessaire pour ce test et les codes de test sont créés pour vérifier si le logiciel se comporte comme prévu.

Test fonctionnel - est effectué sans aucune connaissance du fonctionnement interne du système. Le testeur essaiera d'utiliser le système en suivant simplement les exigences, en fournissant différentes entrées et en testant les sorties générées. Ce test est également appelé test en boîte fermée ou boîte noire.

Test d'acceptation - Il s'agit du dernier test effectué avant la remise du logiciel au client. Elle est réalisée pour s'assurer que le logiciel développé répond à toutes les exigences du client. Il existe deux types de tests d'acceptation - l'un est effectué par les membres de l'équipe de développement, connu sous le nom de test d'acceptation interne (test Alpha), et l'autre est effectué par le client ou l'utilisateur final sous le nom de (test bêta).

Tests d'intégration - Les modules individuels qui sont déjà soumis à des tests unitaires sont intégrés les uns aux autres. Généralement, les deux approches sont suivies:

1) de haut en bas
2) de bas en haut

Shah
la source
Qu'entendez-vous par top-down et bottom-up? Les tests d'intégration sont-ils les mêmes que les tests de bout en bout?
tamj0rd2
18

C'est très simple.

  1. Tests unitaires: il s'agit des tests réellement effectués par les développeurs qui ont des connaissances en codage. Ces tests sont effectués lors de la phase de codage et font partie des tests en boîte blanche. Lorsqu'un logiciel vient pour le développement, il est développé dans le morceau de code ou les tranches de code connues sous le nom d'unité. Et les tests individuels de ces unités appelés tests unitaires effectués par les développeurs pour découvrir une sorte d'erreurs humaines comme le manque de couverture des déclarations, etc.

  2. Tests fonctionnels: Ces tests sont effectués lors de la phase de test (QA) et font partie des tests de la boîte noire. L'exécution réelle des cas de test précédemment écrits. Ce test est en fait effectué par des testeurs, ils trouvent le résultat réel de toute fonctionnalité sur le site et comparent ce résultat au résultat attendu. S'ils ont trouvé une disparité, c'est un bug.

  3. Test d'acceptation: connu sous le nom d'UAT. Et cela est fait par le testeur ainsi que les développeurs, l'équipe de gestion, l'auteur, les écrivains et tous ceux qui sont impliqués dans ce projet. Pour vous assurer que le projet est enfin prêt à être livré sans bugs.

  4. Test d'intégration: Les unités de code (expliquées au point 1) sont intégrées les unes aux autres pour terminer le projet. Ces unités de codes peuvent être écrites dans des technologies de codage différentes ou peuvent être de version différente.Ces tests sont donc effectués par les développeurs pour s'assurer que toutes les unités du code sont compatibles avec les autres et il n'y a aucun problème d'intégration.

Rakesh Kumar
la source
1
@OlegTsyba la réponse est venue 4 ans après la réponse à la question.
bentesha
1
Nous ne devrions jamais commencer une réponse par "C'est très simple", surtout s'il s'agit d'un sujet complexe comme celui-ci.
milosmns
6

Quelques idées (relativement) récentes contre les moqueries excessives et les tests unitaires purs:

cdunn2001
la source
Je suis nouveau dans le test de code. Les tests unitaires semblent surtout être une perte de temps. Je pensais que je faisais des tests unitaires, mais je faisais des tests d'intégration, puis j'ai lu sur les tests unitaires et cela semble idiot, peut-être pour les personnes ayant très peu d'expérience? Il y a une chance que je manque une sorte de point.
PixMach
Si l' unité est définie au sens large, vous testez correctement l'unité. Je m'oppose aux tests de mise en œuvre des détails. Une classe privée ne doit pas être "testée à l'unité". Cependant, si vous avez plusieurs classes publiques, vous pourriez être tenté de vous moquer de l'une en testant une autre. Voilà le vrai débat. L' unité (a) est-elle votre bibliothèque entière? (b) chaque classe publique de la bibliothèque? Ou (c), chaque méthode publique dans chaque classe? Je préfère tester une bibliothèque donnée en tant que composant intégré, mais pour simuler ou simuler des dépendances externes (à moins qu'elles ne soient rapides et fiables). Je pense donc que je suis avec toi.
cdunn2001
1
@PixMach: en fait c'est l'inverse. Ne pas avoir de (bons) tests unitaires en place, vous fait perdre beaucoup de temps si vous (ou quelqu'un d'autre) devez changer ce code à l'avenir. Si vous avez de l'expérience dans la gestion de code avec et sans tests unitaires, vous saurez la différence. L'idée est que si un test unitaire échoue, vous devez savoir exactement quelle partie du code doit être corrigée. L'échec des tests d'acceptation / d'intégration à grande échelle vous dit souvent: cela ne fonctionne pas. Et puis vous devez commencer le débogage de la vieille école ...
Goodsquirrel
@Goodsquirrel, cela dépend de ce que vous appelez une "unité". C'est le problème. Les mauvais tests seront supprimés lors de la refactorisation. De bons tests seront toujours utiles. Les mauvais tests n'apportent aucune valeur et gênent. Les bons tests sont auto-documentés et très appréciés. Soyons précis. J'ai une méthode privée pour renvoyer une valeur si une autre valeur est True, sinon une valeur par défaut. (Code hérité.) Cette méthode doit-elle être testée? Je dis NON. Une autre méthode privée renvoie le nième numéro de Fibonacci. Cela devrait-il être testé? Je dis oui.
cdunn2001
1
Le plus petit code exposé . Grande différence.
cdunn2001
5

Je vais vous expliquer cela avec un exemple pratique et pas de trucs théoriques:

Un développeur écrit le code. Aucune interface graphique n'est encore implémentée. Les tests à ce niveau vérifient que les fonctions fonctionnent correctement et que les types de données sont corrects. Cette phase de test est appelée test unitaire.

Lorsqu'une interface graphique est développée et qu'une application est affectée à un testeur, il vérifie les besoins de l'entreprise avec un client et exécute les différents scénarios. C'est ce qu'on appelle les tests fonctionnels. Ici, nous mappons les exigences du client avec les flux d'application.

Test d'intégration: disons que notre application comporte deux modules: RH et Finance. Le module RH a été livré et testé précédemment. Maintenant, Finance est développé et est disponible pour tester. Les fonctionnalités interdépendantes sont également disponibles maintenant, donc dans cette phase, vous testerez les points de communication entre les deux et vérifierez qu'ils fonctionnent comme demandé dans les exigences.

Les tests de régression sont une autre phase importante, qui est effectuée après tout nouveau développement ou correction de bogue. Son objectif est de vérifier les fonctions précédemment opérationnelles.

fahad shaikh
la source
1
"Un développeur écrit le code. Aucune interface graphique n'est encore implémentée. Les tests à ce niveau vérifient que les fonctions fonctionnent correctement et les types de données sont corrects. Cette phase de test est appelée Test unitaire" Ce n'est pas vrai. L'interface graphique n'est en fait qu'un "plugin". Vous pouvez déjà écrire des tests E2E sur votre sortie API. (ou tout objet de réponse que vous générez)
user3790897
4

test unitaire: le test d'un module individuel ou d'un composant indépendant dans une application est connu pour être un test unitaire, le test unitaire sera effectué par le développeur.

test d'intégration: combiner tous les modules et tester l'application pour vérifier que la communication et le flux de données entre les modules fonctionnent correctement ou non, ce test étant également effectué par les développeurs.

test fonctionnel vérifiant la fonctionnalité individuelle d'une application est un test fonctionnel

test d'acceptation ce test est effectué par l'utilisateur final ou le client, que l'application de construction soit conforme aux exigences du client, et les spécifications du client sont connues pour être des tests d'acceptation

malini
la source