Où dois-je tracer la ligne entre les tests unitaires et les tests d'intégration? Doivent-ils être séparés?

11

J'ai un petit framework MVC sur lequel je travaille. Sa base de code n'est certainement pas grande, mais ce n'est plus seulement quelques classes. J'ai finalement décidé de franchir le pas et de commencer à écrire des tests pour cela (oui, je sais que j'aurais dû le faire tout le temps, mais son API était super instable jusqu'à présent)

Quoi qu'il en soit, mon plan est de le rendre extrêmement facile à tester, y compris les tests d'intégration. Un exemple de test d'intégration irait quelque chose dans ce sens:

Faux objet de requête HTTP -> framework MVC -> objet de réponse HTTP -> vérifier que la réponse est correcte

Parce que tout cela est faisable sans état ou outils spéciaux (automatisation du navigateur, etc.), je pourrais en fait le faire facilement avec des cadres de test unitaires réguliers (j'utilise NUnit).

Maintenant, la grande question. Où dois-je exactement tracer la ligne entre les tests unitaires et les tests d'intégration? Dois-je tester une seule classe à la fois (autant que possible) avec des tests unitaires? De plus, les tests d'intégration doivent-ils être placés dans le même projet de test que mon projet de test unitaire?

Earlz
la source
Le test d'intégration implique de tester plusieurs implémentations réelles de vos composants ensemble (implémentations réelles signifie pas de simulations).
Kemoda
1
Cette question concerne les tests et l'assurance qualité. Je suggère donc de le migrer vers le site correspondant, SQA sur Stack Exchange ( sqa.stackexchange.com )
dzieciou
@dzieciou ne savait même pas que cela existait!
Earlz

Réponses:

19

Intégration vs tests unitaires

Vous devez garder vos tests unitaires et vos tests d'intégration complètement séparés. Vos tests unitaires doivent tester une seule chose et une seule chose et dans l'isolement complet du reste de votre système. Une unité est vaguement définie, mais elle se résume généralement à une méthode ou une fonction.

Il est logique d'avoir des tests pour chaque unité afin que vous sachiez que leurs algorithmes sont correctement implémentés et que vous savez immédiatement ce qui s'est mal passé, si l'implémentation est défectueuse.

Étant donné que vous testez dans l'isolement complet lors des tests unitaires, vous utilisez des objets stub et mock pour vous comporter comme le reste de votre application. C'est là que les tests d'intégration entrent en jeu. Tester toutes les unités isolément est excellent, mais vous devez savoir si les unités fonctionnent réellement ensemble.

Cela signifie savoir si un modèle est réellement stocké dans une base de données ou si un avertissement est réellement émis après l'échec de l'algorithme X.

Développement piloté par les tests

En prenant un peu de recul et en examinant le développement piloté par les tests (TDD), il y a plusieurs choses à prendre en compte.

  1. Vous écrivez votre test unitaire avant d'écrire réellement le code qui le fait passer.
  2. Vous faites passer le test, écrivez juste assez de code pour y parvenir.
  3. Maintenant que le test réussit, il est temps de prendre du recul. Y a-t-il quelque chose à refactoriser avec cette nouvelle fonctionnalité en place? Vous pouvez le faire en toute sécurité car tout est couvert par des tests.

Intégration en premier vs intégration en dernier

Les tests d'intégration s'intègrent dans ce cycle TDD de deux manières. Je connais des gens qui aiment les écrire à l'avance. Ils appellent un test d'intégration un test de bout en bout et définissent un test de bout en bout comme un test qui teste complètement tout le chemin d'un cas d'utilisation (pensez à configurer une application, à la démarrer, à aller vers un contrôleur, à l'exécuter, vérification du résultat, de la sortie, etc ...). Ensuite, ils commencent leur premier test unitaire, le font passer, en ajoutent un second, le font passer, etc ... Lentement de plus en plus de parties du test d'intégration réussissent également jusqu'à ce que la fonctionnalité soit terminée.

L'autre style consiste à créer un test unitaire de fonctionnalité par test unitaire et à ajouter les tests d'intégration jugés nécessaires par la suite. La grande différence entre ces deux est que dans le cas d'un test d'intégration, vous devez d'abord penser à la conception d'une application. Ce genre de désaccord avec la prémisse que TDD concerne autant la conception d'applications que les tests.

Aspects pratiques

À mon travail, nous avons tous nos tests dans le même projet. Il existe cependant différents groupes. L'outil d'intégration continue exécute d'abord ce qui est marqué comme des tests unitaires. Ce n'est que si ceux-ci réussissent que les tests d'intégration sont plus lents (car ils font de vraies demandes, utilisent de vraies bases de données, etc.).

Soit dit en passant, nous utilisons généralement un fichier de test pour une classe.

Lecture suggérée

  1. Développement d'un logiciel orienté objet, guidé par des tests Ce livre est un très bon exemple de la première méthodologie du test d'intégration
  2. L'art du test unitaire, avec des exemples dans dot.net Sur le test unitaire, avec des exemples dans dot.net: D Très bon livre sur les principes du test unitaire.
  3. Robert C. Martin sur TDD (Articles gratuits): Lisez également les deux premiers articles qu'il y a liés.
hoppa
la source
2

Ce qui est important dans toute stratégie de test, c'est la couverture du test - c'est-à-dire pouvoir montrer que toutes les fonctionnalités sont testées.

En général, et sauf si vous avez des exigences spécifiques contraires (par exemple DO178 niveau A, IEC61508 SIL 4, etc.) qui ne semblent pas être le cas dans votre situation, alors si vous pouvez tester la fonction complète de la classe ou d'un module (et démontrer que vous avez) au niveau du système, alors les tests au niveau du système sont adéquats. Et ainsi de suite. Les tests unitaires ne sont nécessaires que lorsque vous n'avez pas couvert les tests plus loin.

Où dois-je exactement tracer la ligne entre les tests unitaires et les tests d'intégration?

Étant donné que les tests d'intégration sont généralement plus faciles, plus rapides et moins chers, tracez la ligne le plus loin possible ...

Dois-je tester une seule classe à la fois (autant que possible) avec des tests unitaires?

Cela dépend de la portée, encore une fois ... par définition, un test unitaire teste une seule unité. Mais si vous pouvez tester un module complet en une seule fois, alors si vous le souhaitez, faites-le. Vous effectuez en fait plusieurs tests unitaires en un seul coup.

De plus, les tests d'intégration doivent-ils être placés dans le même projet de test que mon projet de test unitaire?

Aucune raison fondamentale de ne pas le faire ... à moins que les tests de niveau supérieur ne soient effectués par un testeur indépendant, auquel cas vous ne devriez émettre qu'une instrumentation exécutable et minimale.

Andrew
la source
2
Je ne vois pas comment les tests d'intégration sont plus faciles, plus rapides ou moins chers. Pour moi, c'est le contraire de tous les 3. Et les tests d'intégration sont généralement plus fragiles que les tests unitaires
Earlz
0

Lorsque j'ai de petits projets, je place simplement tous les tests dans le même projet. Étant donné qu'un projet plus important aurait ces divisions, je m'assure simplement qu'il serait possible de les démêler en cas de besoin.

Avec les tests unitaires, je teste généralement une seule classe (SUT) dans un fichier.


la source