Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

L'excès de tests unitaires nuirait au développement agile
Ils seraient favorisés par rapport aux tests d'intégration

Le , par Arsene Newman

0PARTAGES

6  2 
Bien souvent, le développement agile mise sur le développement piloté par les tests (TDD). Aujourd’hui, Mark Balbes, un des membres les plus éminents de Asynchrony Solutions et expert en développement logiciel et en gestion de projet agile, nous livre sa vision des faits en ce qui concerne le TDD.

L’expert estime qu’actuellement, le développement agile use excessivement du TDD, les développeurs ont alors tendances à créer trop de tests surtout avec la multitude d’outils existants sur le marché. Or, une écriture et un choix plus judicieux des tests à utiliser seraient nettement plus bénéfiques pour le développement agile.

En effet, l’apport du TDD est non négligeable, ce dernier préconise l’utilisation de tests unitaires pour vérifier le bon fonctionnement/comportement d’une classe. Les développeurs créent alors des tests unitaires pour chaque entité de leur programme, mais dans certains cas, les tests unitaires s’avèrent inefficaces. Il faut donc songer à utiliser d’autres tests comme les tests d’intégration qui permettent de vérifier si le programme fait le travail souhaité. Il s’agit de vérifier si l’interaction entre les différents objets se fait correctement et se conclut par une exécution correcte du programme.

Ainsi, les tests unitaires diffèrent sensiblement des tests d’intégration, ils permettent de vérifier le fonctionnement de chaque classe indépendamment des autres. Toutefois, ils ne garantissent pas l’interaction correcte des objets. Pourtant, le développeur se préoccupe en premier lieu du bon fonctionnement du programme dans son ensemble. C’est là qu’il y aurait contradiction avec les pratiques de certains.

L’expert recommande donc aux développeurs de s’affranchir d’une utilisation trop récurrente des tests unitaires qui tirent leur source du TDD et d’utiliser à bon escient chaque type de test : des tests unitaires pour les classes qui traitent des données et des tests d’intégration pour les objets qui interagissent entre eux et qui modifient/déplacent des données, car après tout l’esprit agile c’est aussi une souplesse de l’esprit.

Source : Billet de blog de Mark Balbes

Et vous ?

Qu’en pensez-vous ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Luckyluke34
Membre émérite https://www.developpez.com
Le 26/05/2014 à 11:53
And why did we do this? We don't really care about how the objects work together. We care that the system behaves correctly as a whole.
Sous une apparence de bon sens, cette phrase cache une fausse bonne idée qui me parait dangereuse si on l'applique à la lettre.

Si on a un graphe de 2, 5, 10 objets, et qu'on se fixe comme unique objectif de vérifier ce qui se passe à chaque bout de cette chaine, on va être tenté de ne tester que les cas nominaux et quelques cas d'erreur les plus courants, sans se poser la question de la validité des objets intermédiaires dans des scénarios très spécifiques. Les tests unitaires ont cette vertu qu'ils nous forcent à nous intéresser à chaque petit composant et nous interroger sur le contrat qu'il doit fournir, le protocole d'échange de messages avec ses collaborateurs, les plages de valeurs qu'il peut et ne peut pas accepter, etc. A l'inverse, plus les tests d'intégration portent sur un gros graphe d'objets, plus il est difficile d'imaginer des scénarios et des combinaisons qui sortent des sentiers battus et provoquent une erreur inattendue. Même en supposant qu'on arrive à les discerner, il sera plus difficile de mettre notre grappe d'objets non isolés dans la configuration voulue, aboutissant en général à des tests lents et avec une étape de setup très compliquée.

Quand on regarde les récents bugs retentissants dans OpenSSL (HeartBleed), dans iOS, ils auraient pu être évités grâce à des micro-tests ciblés qui vérifient la validité d'une unité de code vis-à-vis de cas non nominaux.

Il y a une autre (meilleure ?) façon de s'assurer de cette validité basique du comportement d'un objet, c'est l'approche Design By Contract : rajouter des pré- et post-conditions aux méthodes pour spécifier ce qu'elles peuvent accepter et ce qu'on attend d'elles. Les tests/spécifications unitaires deviennent alors intégrés au code de production.

Bien sûr que ce qui nous intéresse, c'est que le système entier se comporte correctement, mais le diable se trouve dans les détails de ce "comportement correct". Dans quels scénarios ? Avec quelles données ? Quel niveau de tolérance aux défaillances matérielles ou logicielles d'autres systèmes ? Pour moi, les tests unitaires permettent de débusquer tous ces lièvres bien mieux que des tests plus larges.
6  0 
Avatar de yashiro
Membre régulier https://www.developpez.com
Le 15/06/2014 à 8:38
Je pense pour ma part qu'il faut dissocier le principe des tests unitaires/intégration de leurs usages par les développeurs. C'est pas parce que certains développeurs utilisent peu/trop/mal ces types de tests qu'il sont bon/mauvais en soi,
De plus, je suis aussi convaincu que plus le projet est gros, plus il faut tester les différents composants de façon unitaire et intégrée selon les chemins nominaux et alternatifs.
Mais le plus important pour moi c'est que dans un projet, il faut définir des normes de développement qui permettront de décrire (entre autres) comment un code doit être écrit et testé. Un développeurs de l'équipe ne devrait pas écrire un(des) test(s) selon son bon vouloir, mais il doit être guidé par une norme de développement définie en amont et contrôlée automatiquement par des outils d'intégration continue.

Dans les projets dont je suis responsable, les tests unitaires sont hyper important parce qu'ils me permettent de m'assurer du bon fonctionnement des différents composants et les tests d'intégration me permettent de valider leur fonctionnement couplés en considérant que s'il ya des erreurs, celles-ci ne viennent pas du fonctionnement propre des composants mais plutôt de leur intégration: de ce fait, je vais beaucoup plus vite dans la localisation des bugs et dans leur correction.
3  0 
Avatar de Jay13mhsc
Membre du Club https://www.developpez.com
Le 29/05/2014 à 22:08
Et un jour, @jbrains a dit : http://www.jbrains.ca/series/integra...sts-are-a-scam

On a jamais dit qu'un TU portait sur une seule classe...
Quand on teste, on le fait sur une interface stable. Point.
2  0 
Avatar de DonQuiche
Expert confirmé https://www.developpez.com
Le 26/05/2014 à 19:33
Citation Envoyé par Arsene Newman Voir le message
En effet, l’apport du TDD est non négligeable, ce dernier préconise l’utilisation de tests unitaires pour vérifier le bon fonctionnement/comportement d’une classe.
Je ne suis pas d'accord avec cette affirmation : si tel était le cas il n'y aurait pas d'intérêt à écrire les tests avant. Si le test-driven development préconise d'écrire d'abord les tests c'est parce que cela force le développeur à partir du haut (le contexte d'utilisation de la classe, les spécifications, etc) plutôt que du bas (l'algorithme). Dans ce contexte le test ne sert pas à tester mais d'abord à concevoir !

Et pour ce qui est du choix des tests, il y a effectivement une gamme d'outils disponibles dont les test unitaires ne sont qu'un maillon et pas toujours indispensables ou judicieux (et encore moins souvent le plus judicieux si l'équipe a décidé d'allouer peu de moyens aux tests).
1  0 
Avatar de Matthieu Vergne
Expert éminent https://www.developpez.com
Le 01/06/2014 à 15:10
Dans l'ensemble, ça part d'une bonne intention : trop de quelque chose, c'est comme pas assez, ce n'est jamais bon. Le principal message (de ce que j'ai compris de l'article) est que certains croient dur comme fer à la primauté des test unitaires et mettent des ressources à l'excès sur ce point. Ce que préconise ce monsieur est d'être moins fanatique (pour ceux qui le sont) et de répartir les efforts sur plusieurs types de test, ce qui en soit me semble être censé.

Cela dit, je rejoins le point de certains : il ne faut pas tomber dans l'excès inverse en concentrant tous ses efforts sur des tests d'intégration sans se préoccuper du bon déroulement interne. Sinon on fait de la programmation génétique (création et évolution automatique de programmes) en cherchant à maximiser les tests d'intégration qui passent. Inutile de savoir programmer, on fait des tests d'intégrations à gogo et basta.

De la même manière qu'on prouve un théorème pas-à-pas, on fait un programme qui marche bien pas-à-pas. Les briques internes doivent être bien faites pour que l'ensemble tienne, tout comme l'ensemble doit être organisé correctement pour que ça ressemble à quelque chose.

Pour ma part, j'estime qu'il est stupide de faire une différence entre tests unitaires et tests d'intégration (et autres types de tests) car l'idée véhiculée en général est que tout projet doit avoir une hiérarchie de tests donnée, ce qui à tendance à foirer lamentablement si on le prend à la lettre. Si on développe une lib, qu'est-ce que ça veut dire d'avoir des tests d'intégration ? Est-ce à la lib de faire ces tests, et donc de vérifier dans tous les cas où elle peut-être utilisée si ça marche correctement ? Infaisable. Est-ce au programme qui l'utilise de le vérifier ? Mais si oui, alors qu'est-ce qu'un test d'intégration au niveau de la lib ? Ça ne peut pas être un test qui vérifie qu'une sous-lib (lib pour la lib) s'intègre correctement, vu que ça serait au même niveau que des tests unitaires, hors un test d'intégration est censé être plus haut niveau.... {_~_}

De mon point de vue, un test permet de vérifier que tout se passe bien dans un contexte donné, que ce soit un contexte très bas niveau ou très haut niveau. Quand je programme, je design mon programme en identifiant des concepts et leurs relations pour établir des interfaces, en les réduisant au minimum pour avoir quelque chose de simple. Quand je les implémentent, si j'ai besoin de fonctionnalités avancées (et que je n'ai pas de lib pour le faire), je réfléchis séparément à ces fonctionnalités en établissant des concepts et leurs relations pour établir leurs interfaces, que j'implémente, et ainsi de suite. Je n'hésite pas d'ailleurs à faire des projets séparés quand je sens que ça peut être réutilisé. À chacun de ces niveaux, je fais des tests qui correspondent au contexte précis que je design et que j'implémente. De ce fait, les tests effectués à bas/haut niveau correspondent à des tests unitaires/d'intégration, mais dans l'esprit ce ne sont ni plus ni moins que le même genre de tests que je fais dans différent contextes : ils servent à vérifier que l'implémentation de mes interfaces, au niveau donné, correspond à mon cahier des charges pour ce niveau, point final. C'est une approche de test très modulaire, autant que la modularité du programme en lui-même, et qui permet de se focaliser sur un contexte donné sans commencer à réfléchir à comment il est censé interagir une fois associé à telle ou telle autre fonctionnalité. Sinon on fait du code spaghetti non-maintenable et très dur à reprendre.
1  0 
Avatar de Marco46
Expert éminent sénior https://www.developpez.com
Le 16/06/2014 à 11:56
Citation Envoyé par souviron34 Voir le message
Je crois qu'on t'a déjà fait la remarque plus haut, mais je vais la refaire :
Bah pareil.

Citation Envoyé par souviron34 Voir le message

Quand on parle de "projets", faut savoir de quoi on parle.. Durant mes 30 ans de carrière en informatique, le plus petit de mes projets avait 60 000 lignes, le plus gros 5 millions, la moyenne entre 500 000 et 2 millions, avec environ de 14 000 à 40 000 points de fonction.
Et ? Quel rapport entre la taille d'un projet et les tests ?

Citation Envoyé par souviron34 Voir le message

Faire des TU automatiquement sur toutes les fonctions d'un tel projet revient à revenir purement et simplement au cycle en V.
Non ça revient à tester son application, point.

Citation Envoyé par souviron34 Voir le message
D'autre part, bien sûr que si que ça a à voir avec la responsabilité et l'agilité : c'est ce qui permet de "zapper" certaines parties du développement en V... PARCE QUE les personnes sont responsables et jugées compétentes dans leurs domaines.
Mais arrête avec ton développement en V t'es hors sujet bonhomme. Tu fais une association entre un outil (les TU) et une méthode (le cycle en V). Quand tu as l'un tu n'as pas forcément l'autre.

Citation Envoyé par souviron34 Voir le message

Enfin tu montres tes limites : tu te fixes sur des classes et du langage objet. Mais sache que bon nombre de projets ne fonctionnent pas ainsi.
Merci. Et donc ?

Citation Envoyé par souviron34 Voir le message
Mais même en ne prenant que ça, faire un TU sur une méthode qui ne fait que 2 opérations par exemple , ça se fait, mais on n'a pas besoin ni de le documenter, ni de s'y arrêter : c'est le fait que tu es bon qui fait que tu le fais..
Si tu as écrit des tests sur une méthode, tu as besoin de peu avoir de pas de documentation. Encore un intérêt supplémentaire aux tests.

Citation Envoyé par souviron34 Voir le message

Sinon tu retombres exactement dans le piège du cycle en V : pour pouvoir tout vérifier, tu écris tout et documentes tout.. Ce qui est antinomique de l'agilité..
Tu as une fausse idée de l'utilisation des TU dans un contexte agile. Cela permet la souplesse contrairement à ce que tu dis.

Sur les durées du projet c'est l'histoire du lièvre et de la tortue. Certes écrire des tests donne l'impression de couter plus cher au début mais au final tu y gagnes.
1  0 
Avatar de Matthieu Vergne
Expert éminent https://www.developpez.com
Le 16/06/2014 à 13:51
Qu'on fasse du cycle en V ou de l'agile, des tests on en a (ou peut en avoir) dans les 2. La grosse différence est sur l'organisation générale : dans un cas on fait une grosse itération, dans l'autre plusieurs petites. Dans un cas, le contrôle est soutenu pour éviter la moindre boulette qui pourrait faire foirer la suite, dans l'autre le contrôle est dilué mais répété.

Le titre du sujet parle de lui-même : dès lors qu'on a un excès, c'est pas bon, quel que soit le contexte. Un excès de tests est par définition du "trop qui peut être réduit avantageusement", que ce soit en agile ou en cycle en V. À pinailler sur quelle méthode implique quels tests ou je ne sais quoi, c'est un bon moyen de troller, mais à part ça...
1  0 
Avatar de Luckyluke34
Membre émérite https://www.developpez.com
Le 16/06/2014 à 17:14
Citation Envoyé par transgohan Voir le message
Tu avait une vision de projet que Souviron et moi n'avons pas. (je suis d'ailleurs content de trouver un camarade qui semble savoir ce qu'est un gros projet)
Il y a des projets qui sont énormes (d'ailleurs en réponse à mon premier post tu ne me croyais pas et il a fallu que j'indique que ce n'était que des chiffres sortis d'un projet existant)
Je ne suis pas persuadé qu'un concours de kiki de qui a le plus gros projet apporte grand chose à ce débat (ni à d'autres d'ailleurs)

Quand on dit "il n'y a pas de rapport entre la taille d'un projet et les tests unitaires", c'est que la valeur apportée par les TU n'est pas fonction du nombre de lignes de ton projet. Si un médecin estime nécessaire de changer ses gants entre chaque patient, il ne va pas arrêter de le faire parce qu'il a 50 patients au lieu de 10 dans une journée.

Citation Envoyé par transgohan Voir le message
Or quand un projet est vendu, le temps associé pour le réaliser compte rarement le temps réel pour faire les tests.
Il faut donc converger sur ce qu'il y a de plus judicieux et de plus rapide.
Peut-être, mais je reste persuadé que les tests unitaires permettent de penser en profondeur une unité de code, ses cas nominaux mais aussi ses cas limites, les plages de valeurs valides, de mettre à jour ses dépendances implicites et explicites pour mieux les agencer...

Plus particulièrement, selon mon expérience, écrire un test unitaire avant le code correspondant permet de concevoir son code en étant focalisé sur une seule fonctionnalité à faire passer et d'être sûr qu'elle marche. Avec un test écrit après, a fortiori un test grosse maille, on travaille plus au jugé en risquant de mésestimer tous les cas qui se produiront à l'exécution.
1  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 26/05/2014 à 17:42
Citation Envoyé par Arsene Newman Voir le message

L’expert recommande donc aux développeurs de s’affranchir d’une utilisation trop récurrente des tests unitaires qui tirent leur source du TDD et d’utiliser à bon escient chaque type de test : des tests unitaires pour les classes qui traitent des données et des tests d’intégration pour les objets qui interagissent entre eux et qui modifient/déplacent des données, car après tout l’esprit agile c’est aussi une souplesse de l’esprit.
Mais une souplesse de l'esprit de ne veut pas dire livrer un produit avec des bugs, ceci est totalement contre la démarche qualité du projet. Si on se focalise sur les testes d’intégrations et on ne voit que la bonne marche du programme selon le but spécifique du client, Il suffit qu'on pense à l'évolution du projet pour qu'après ces bug apparaissent.

Vouloir faire entrer l'agile même dans le fond du métier du codage c'est passer à côté de la plaque. L'agilité c'est dans le processus et non pas sur les choses clés du codage et qui sont fortement recommandé par toute démarche qualité.

Il ne faut pas voir teste unitaire comme juste le fait d'écrire toute une séries de testes unitaire automatisés , mais le fait de chaque méthode soit testé si elle marche correctement selon tous les types de données possibles en paramètre et les types normalement attendus, comme on dit teste unitaire: c'est tout simplement le teste d'une petite unité du programme. Alors selon lui, il veut qu'on diminue ça et on privilégie la partie intégration entre plusieurs unités du programmes
Mais c'est exploser le temps de la correction de bug, voir impossible de connaitre d'où vient certains bugs.

Si j'ai une méthode m1 et m2 qui ne sont pas bien testés à tous les coups et je les intègre ailleurs pour donner le résultat d'une fonctionnalité X, alors je fais que je m'intéresse au fait que la fonctionnalité X fonctionne correctement et que ça suffit comme teste de m1 et m2, c'est grave Car il suffit d'avoir à intégrer m2 avec un m3 d'autre part pour une fonctionnalité Y pour que j'obtienne un bug, oui m2 cachait un bug qui n'est pas vu quand j'ai testé X.

Pire encore, je vas revenir pour corriger le bug caché de m2, je vais en produire d'autres sans me rendre compte. oops : X ne fonctionne pas correctement Régression !!! Ils ne sont pas fous ceux qui ont pensé au outils d’intégration continue, mais comment les utiliser si on a pas une base de testes unitaires pour tous les unités du programme? C'est de la merde.
Citation Envoyé par Arsene Newman Voir le message

Qu’en pensez-vous ?
Qu'on ne fait qu'encourage les mauvaises pratiques, et un ingénieur qui apprend un maçon comment bien placer ces briques. C'est fini on ne fait que dire bonjour aux
2  2 
Avatar de el_slapper
Expert éminent sénior https://www.developpez.com
Le 26/05/2014 à 21:34
Pour filer la métaphore du maçon : le mur doit être bien construit, et chaque brique doit être conforme.
0  0