65 votes

Pourquoi les tests unitaires ne devraient-ils tester qu'une seule chose?

Ce qui Fait un Bon Test de l'Unité? dit qu'un test doit tester une seule chose. Quel est l'avantage de qui?

Ne serait-il pas préférable d'écrire un peu plus gros tests test le plus gros bloc de code? Enquête sur un échec du test est de toute façon difficile et je ne vois pas d'aide de petits tests.

Edit: Le mot unité n'est pas si important que cela. Disons que je considère que l'unité d'un peu plus grand. Ce n'est pas la question ici. La vraie question est pourquoi faire un test ou plus pour toutes les méthodes que quelques tests qui couvrent de nombreuses méthodes est plus simple.

Un exemple: Une liste de classe. Pourquoi devrais-je faire des tests distincts pour l'ajout et la suppression? Un test qui ajoute d'abord puis supprime les sons plus simple.

85voto

MrBoJangles Points 4677

Tester une seule chose va isoler qu'une seule chose et prouver si oui ou non cela fonctionne. C'est l'idée de l'unité de test. Rien de mal avec les tests de tester plus d'une chose, mais qui est généralement appelé test d'intégration. Ils ont tous deux mérites, basée sur le contexte.

Pour utiliser un exemple, si votre lampe de chevet ne s'allume pas, et vous, remplacer l'ampoule et de changer le cordon de rallonge, vous ne savez pas quel changement correction du problème. Il devrait y avoir fait les tests unitaires, et séparées l'une de vos préoccupations pour isoler le problème.

78voto

Jon Skeet Points 692016

Je vais aller sur une branche ici, et dire que "le seul test d'une chose" avis n'est pas vraiment utile, car il est parfois.

Parfois, des tests de prendre une certaine quantité de configuration. Parfois, ils peuvent même prendre une certaine quantité de temps à mettre en place (dans le monde réel). Souvent, vous pouvez tester les deux actions en une seule fois.

Pro: seulement toutes que le programme d'installation se produire une fois. Vos tests après la première action sera de prouver que le monde est de savoir comment vous vous attendez à ce qu'il soit avant la deuxième action. Moins de code, plus rapide essai.

Con: si soit l'action échoue, vous obtiendrez le même résultat: le même test échouera. Vous aurez moins d'informations sur l'endroit où le problème est que si vous n'aviez qu'une seule action dans chacun des deux tests.

En réalité, je trouve que le "con" ici n'est pas beaucoup d'un problème. La trace de la pile, souvent, se rétrécit vers le bas très rapidement, et je vais m'assurer de corriger le code de toute façon.

Un peu différent "con" ici, c'est qu'elle casse l' "écrire un nouveau test, le faire passer, refactor" cycle de. J'ai vue que comme un idéal cycle, mais qui n'est pas toujours le miroir de la réalité. Parfois, il est simplement plus pragmatique pour ajouter une action supplémentaire et vérifier (ou peut-être juste une autre vérification à une action existante) dans un test en cours plutôt que d'en créer un nouveau.

(Je m'attends à être downvoted fortement sur cette réponse - c'est une honte, c'est près de la fin de la journée au lieu de le commencer, mais jamais l'esprit. J'espère qu'il y aura vraiment de très bonnes raisons de mon wrongheadedness dans les commentaires, et c'est plus important que de rep.)

13voto

swilliams Points 19415

Les Tests qui permettent de vérifier plus d'une chose ne sont généralement pas recommandés parce qu'ils sont plus étroitement couplé et cassants. Si vous changez quelque chose dans le code, ça va prendre plus de temps pour changer le test, car il y a plus de choses à prendre en compte.

[Edit:] Ok, disons que c'est un exemple de méthode de test:

[TestMethod]
public void TestSomething() {
  // Test condition A
  // Test condition B
  // Test condition C
  // Test condition D
}

Si votre test de condition échoue, B, C et D d'échouer, et ne sera pas vous fournir toute l'utilité. Que faire si votre changement de code aurait causé C à l'échec? Si vous aviez divisé en 4 épreuves distinctes, vous savez cela.

11voto

Newtopian Points 3335

Haaa... les tests unitaires.

Poussez toutes les "directives" trop loin et il devient rapidement inutilisable.

Seule unité de test test une seule chose, c'est juste comme une bonne pratique comme méthode unique n'a qu'une seule tâche. Mais à mon humble avis cela ne veut pas dire un seul test ne peut contenir qu'une seule instruction assert.

Est

@Test
public void checkNullInputFirstArgument(){...}
@Test
public void checkNullInputSecondArgument(){...}
@Test
public void checkOverInputFirstArgument(){...}
...

mieux que

@Test
public void testLimitConditions(){...}

est question de goût, à mon avis, plutôt que d'une bonne pratique. Personnellement, je préfère de beaucoup le dernier.

Mais

@Test
public void doesWork(){...}

est effectivement ce que la "directive" veut vous faire éviter à tout prix, et à ce que les drains de ma santé mentale le plus rapide.

En conclusion, le groupe ensemble de choses qui sont sémantiquement liées et facilement vérifiables ensemble, de sorte que l'échec d'un message de test, par lui-même, est en fait assez significative pour vous rendre directement sur le code.

Règle de base ici sur l'échec d'un rapport d'essai: si vous devez lire le test du code d'abord, puis votre test ne sont pas structurés assez bien et ont besoin de plus de fractionnement en petits tests.

Mes 2 cents.

6voto

tvanfosson Points 268301

À l'aide de test-driven development, vous pouvez écrire vos tests abord, puis d'écrire le code pour passer le test. Si vos tests sont concentrés, ce qui rend l'écriture du code pour passer le test plus facile.

Par exemple, je pourrais avoir une méthode qui prend un paramètre. Une des choses que je pourrais penser de la première, ce qui devrait se produire si le paramètre est null? Il faut jeter un ArgumentNull exception (je pense). Alors, j'ai écrit un test qui vérifie si l'exception est levée lorsque je passe un argument null. Exécuter le test. Bon, il jette NotImplementedException. Je vais corriger cela en modifiant le code de jeter un ArgumentNull exception. Exécuter mon test il passe. Et puis, je pense, qu'advient-il si il est trop petit ou trop grand? Ah, c'est deux essais. J'écris trop petit.

Le point est que je ne pense pas que le comportement de la méthode tout à la fois. - Je construire progressivement (et logiquement) en pensant à ce qu'il devrait faire, puis de mettre en œuvre et de refactoring de code que je vais pour le faire paraître jolie (élégant). C'est pourquoi les tests doivent être de petite taille et concentré parce que quand vous êtes à la réflexion sur le comportement que vous devez développer dans les petites, compréhensible par incréments.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X