tests fonctionnels automatisés: ils sont écrits par les fonctionnels et sont "lisibles par un humain".
Finalement, "s'il y a des doublons, c'est une coïncidence, en quelque sorte :)".
Idée: On a vraiment des doublons, lorsque, sur un projet, ce sont les développeurs qui font aussi les tests fonctionnels et qu'ils sont les seuls à les lire ou les mettre à jour. Dans ce cas, il est intéressant de se poser la question de l'utilité de ces tests: il y a fort à parier qu'on pourrait se contenter de tests développeurs JUnit.
Les tests unitaires et les tests fonctionnels sont également différents dans leur granularité: les tests unitaires sont "boite blanche" (c'est à dire qu'ils testent le code... "ils regardent sous le capot")...alors que les tests fonctionnels sont "boite noire" (ils testent l'application de bout en bout). Si les tests se ressemblent trop dans leur structure ou leurs assertions, c'est probablement que leur granularité est à retravailler.
Idée 1: On rencontre sur beaucoup de projet des tests "boite noire" développés avec JUnit: ce sont les tests d'intégration. Ils passent par plusieurs services, DAOs, par la base de données, etc. Ces tests sont utiles car ils permettent de tester la communication entre les couches, la configuration, etc. Mais ils sont généralement lents à exécuter. Il faut donc les utiliser avec précaution ! Deux raisons possibles à l'utilisation massive de ces tests d'intégration: ou bien le projet ne dispose pas d'outils dédiés aux tests "boite noire" (FitNesse, GreenPepper, Selenium, etc.), ou bien ceci est dû à une méconnaissance des outils de Mock et des pratiques associées. Quelle qu'en soit la cause, limiter le nombre de ces tests "d'intégration" au profit de tests plus "unitaires" permet de réduire considérablement la durée globale d'exécution des tests. Et avoir des tests rapides, cela permet de les exécuter souvent, et donc de détecter les anomalies plus tôt.
Idée 2: Séparer les tests unitaires (rapides) des tests d'intégration (lents) est une bonne pratique. Ceci peut se faire par convention de nommage des classes de test, répertoires séparés, annotations ou autre. Une fois les tests JUnit catégorisés, des outils comme Maven permettent de définir des règles du type "les tests unitaires se lancent sur le poste développeur, les tests d'intégration s'exécutent uniquement sur le serveur d'intégration continue". Cette séparation permet d'éviter le travers (récurrent) suivant: "les tests sont trop longs, je ne les exécute pas localement et les délègue à l'intégration continue".
Enfin, et c'est le point le plus important, les tests unitaires et les tests fonctionnels automatisés poursuivent des objectifs complémentaires:
Nos projets intègrent plusieurs types de tests. Parmi eux, les tests unitaires et les tests fonctionnels couvrent les mêmes fonctionnalités, il est donc normal d'avoir le sentiment qu'ils se recoupent parfois.
Cependant, ils sont écrits par des personnes différentes, avec des niveaux de granularité différents et, surtout, des objectifs complémentaires: - Faire bien le produit, pour les uns - Faire le bon produit, pour les autres
En revanche, c'est au niveau des tests unitaires ou d'intégration qu'il est important de commencer la chasse aux doublons ! La durée de votre build ne s'en portera que mieux!
Un grand merci à Ismaël Héry, Julien Jakubowski, Eric Pantera, Arnaud Huon, Rémy-Christophe Schermesser, Christophe Thibault, Henri Tremblay, Maria-Dolores Manzanedo, Sylvain Fagnent, Bertrand Paquet, Sylvain Mazaleyrat et Florian Marin pour ces échanges et retours d'expérience enrichissants !