Tests de bout en bout par rapport aux tests unitaires, les tests devraient-ils être découplés?

23

Dans notre entreprise, nous nous assurons généralement de rédiger un test de bout en bout pour nos sites Web / applications Web. Cela signifie que nous accédons à une URL, remplissons un formulaire, soumettons le formulaire à une autre URL et vérifions les résultats de la page. Nous faisons cela pour tester la validation du formulaire, vérifier que les modèles HTML ont les variables de contexte correctes, etc.

Nous l'utilisons également pour tester indirectement la logique sous-jacente.

Un collègue m'a dit que la raison en est que nous pouvons extraire et modifier l'implémentation sous-jacente à tout moment tant que les tests de bout en bout réussissent.

Je me demande si ce type de découplage est logique ou si c'est juste un moyen d'éviter d'écrire des tests pour des unités de code plus petites?

Rudolf Olah
la source
6
was told by a co-worker that the reason for this is that we can rip out and change the underlying implementation at any point as long as the end-to-end tests pass.- Cela vaut également pour les tests unitaires. Il me semble que les tests de bout en bout sont utilisés comme excuse pour ne pas écrire de tests unitaires.
Robert Harvey
12
Ce n'est pas le cas des tests unitaires. La modification / suppression / création de méthodes ou de classes nécessite de mettre à jour tous les tests unitaires de ces méthodes ou classes. Ce n'est pas le cas dans les tests de bout en bout, sauf si la fonctionnalité de l'utilisateur final change. Tant qu'il s'agit d'un refactorisateur au niveau du système (aucune modification des fonctionnalités de l'utilisateur final), aucune modification n'est requise pour les tests de bout en bout.
dietbuddha
2
@dietbuddha, je pense que le concept général est vrai pour les tests unitaires, mais à une portée (unitaire) plus petite.
Sam

Réponses:

38

Des tests de bout en bout sont également nécessaires. Sinon, comment pouvez-vous savoir que vous avez correctement connecté toutes les unités? Sur du code très simple, il est possible de tester tous les chemins à travers le code avec seulement des tests de bout en bout, mais à mesure que vous obtenez plus de couches, cela devient beaucoup plus coûteux de le faire.

Par exemple, supposons que vous ayez trois couches, chacune avec cinq chemins possibles. Pour tester tous les chemins à travers l'application entière, il faudrait 5 3 tests de bout en bout, mais vous pouvez tester tous les chemins à travers chaque unité avec seulement 5 · 3 tests unitaires. Si vous ne faites que des tests de bout en bout, de nombreux chemins finissent par être négligés, principalement dans la gestion des erreurs et les conditions aux limites.

Karl Bielefeldt
la source
Voilà une bonne réponse. Je vois la valeur des deux, mais voir le nombre de possibilités de tester complètement tous les chemins avec des tests de bout en bout est utile pour expliquer pourquoi les tests unitaires doivent être effectués plus que ce n'est le cas
Rudolf Olah
14
Je considère que les tests unitaires sont utiles, car ils localisent rapidement les problèmes. De bout en bout sont précieux car ils vous donnent l'assurance que tout fonctionne ensemble.
Jason Swett
20

Oui, les tests de bout en bout (ou tests d'intégration) ont beaucoup de sens, mais les tests unitaires aussi. Idéalement, vous les avez tous les deux, car les deux attrapent généralement différents types de bogues. Ainsi, avoir des tests de bout en bout ne devrait jamais être une excuse pour ne pas avoir de tests unitaires.

Doc Brown
la source
2
Une note rapide sur le libellé; même si ce n'est pas une science exacte, beaucoup de gens diront que les tests de bout en bout et les tests d'intégration sont des choses différentes. Voir stackoverflow.com/questions/4904096/…
sbrattla
6

Après quelques années de codage et de travail sur des projets, je répondrai à ma propre question.

Oui, vous devez écrire des tests unitaires. Les tests de bout en bout sont plus difficiles à écrire et fragiles, surtout s'ils s'appuient sur des composants d'interface utilisateur.

Si vous utilisez un framework comme Django ou Rails (ou vos propres classes personnalisées), vous devriez avoir une classe de formulaire qui gérera la validation du formulaire. Vous aurez également des classes d'affichage qui affichent des modèles rendus et le formulaire et gèrent les demandes GET et POST.

Dans un test de bout en bout, vous devez:

  1. obtenir l'url
  2. remplissez le formulaire avec des données valides
  3. poster le formulaire dans l'url
  4. vérifiez que la base de données a été mise à jour ou qu'une action a été exécutée à la suite du formulaire valide

Vous testez beaucoup de code et votre couverture sera plutôt bonne, mais vous ne testez le chemin heureux que lorsque tout va bien. Comment vous assurez-vous que le formulaire contient la bonne validation? Et si ce formulaire est utilisé sur plusieurs pages? Ecrivez-vous encore un autre test de bout en bout?

Essayons à nouveau avec des tests unitaires:

  1. tester la méthode GET view
  2. tester la méthode view POST avec une fausse / fausse forme
  3. tester le formulaire avec des données valides
  4. tester le formulaire avec des données invalides
  5. tester les effets secondaires du formulaire

En utilisant des tests unitaires, vous testez des morceaux de code plus petits et les tests sont spécifiques et plus faciles à écrire. Lorsque vous combinez cela avec TDD (Test Driven Development), vous obtenez un code de meilleure qualité.

La facilité d'écriture des tests unitaires ne doit pas être écartée car lorsque vous êtes sur un projet qui n'a pas de test automatisé, vous devez commencer quelque part. Commencer par des tests unitaires est plus facile et plus rapide et vous permet de commencer immédiatement à tester les bogues plutôt que seulement pour le chemin heureux.

Rudolf Olah
la source
un autre point de données, Google Testing Blog dit non à plus de tests end2end : googletesting.blogspot.ca/2015/04/…
Rudolf Olah
5

En fait, les tests de bout en bout ou les tests d'intégration sont plus importants que les tests unitaires car ils garantissent que vous disposez d'un système pleinement opérationnel. Les tests unitaires ne couvrent pas la partie intégration d'un système, ce qui est une tâche compliquée, en particulier dans les grands projets.

Cependant, comme cela a été dit, vous devriez également faire des tests unitaires, car il est plus compliqué de détecter les cas limites dans les tests d'intégration.

m3th0dman
la source
1

Il vérifie le comportement du système, tandis que les tests unitaires vérifient le comportement de l'unité. Les avantages et les coûts pour chacun sont différents. Vous pouvez faire l'un ou l'autre ou les deux.

Dans mon travail, nous faisons du développement piloté par des tests d'acceptation sans tests unitaires, ce qui ressemble à ce que vous avez décrit. Nous avons commencé à faire les deux et au fil du temps, puis nous avons finalement éliminé les tests unitaires pour un coût dépassant les avantages pour nous.

Cela étant dit, je pense que le rapport coût / avantage pour votre domaine et votre environnement de problème devrait conduire les décisions de s'engager dans n'importe quelle pratique de développement, différentes pratiques de test automatisées incluses. Plutôt que la foi, je préfère que toutes les pratiques aient des preuves empiriques dans le contexte de leur utilisation pour les soutenir.

Dietbuddha
la source
Ce qui m'inquiète, c'est que nous allons coder vers des tests d'acceptation qui conduisent à de grandes classes ou méthodes au lieu de petites unités.
Rudolf Olah
@omouse: Ce n'est pas parce que vous n'écrivez pas de tests unitaires qu'il n'y a pas de bon code à écrire. Cependant, si vous avez des programmeurs inexpérimentés ou qui ont simplement de mauvaises habitudes, les avantages peuvent l'emporter sur les coûts. Dans les deux cas, vous devez faire l'analyse et la réduire à une simple équation. For Any Practice: Practice iff Benefit > Cost
dietbuddha