Mon année 2014 – Les tests d’acceptation – 3 – les tests d’acceptation et les tests unitaires
Apres avoir vu que les tests d’acceptation sont un element crucial du Done, et à quel point ils sont nécessaires à la communication, voyons ou se place ce type de tests par rapport aux tests unitaires.
Les auteurs de l’excellent livre “Growing Oriented Object Software Guided By Tests” (Une référence que tout développeur devrait lire, à mon avis) décrivent les tests d’acceptation comme des tests qui exercent le système de bout-en-bout sans appeler son code interne.
Un test de bout-en-bout interagit avec le système uniquement de l’externe, via l’interface utilisateur, en lui envoyant des messages comme une tierce partie, en appelant un webservice, etc.
Le comportement Global du système inclut son interaction avec l’environnement externe. Ceci est souvent l’aspect le plus risqué, le plus difficile, mais aussi le plus souvent ignoré.
Les auteurs expliquent qu’il faut essayer d’éviter les tests d’acceptation qui exercent uniquement des objets internes du système.
La question des niveaux de tests est un sujet en soi, et plusieurs auteurs ont plusieurs definitions. En voici une version que je trouve assez simple et claire :
Nous pouvons faire la distinction entre deux types de qualité dans un système:
La qualité externe : qui décrit comment le système répond au besoins des clients et utilisateurs. Il fonctionne, il est fiable, disponible etc.
Le cas de la qualité externe est simple à comprendre, ca fait partie du contrat a livrer.
La qualité interne : qui décrit comment le système répond aux besoin de ses développeurs et administrateurs. il est facile à comprendre, facile à changer etc.
Le cas de la qualité interne est plus subtile, il a plutôt rapport avec l’anticipation du continuel changement.
Maintenir la qualité interne nous permet de modifier le comportement du système en toute sécurité. De plus, elle nous permet une sorte de “prédictabilité” puisqu’elle minimise le risque qu’un changement nous oblige à retravailler une majeure partie du système
Le graphique ci-dessous expose l’apport de chaque niveau de tests sur deux axes : la quantité de feedback et l’évolutivité
Les tests de bout-en-bout nous exposent la qualité externe du système. Les écrire nous permet de determiner a quel point nous, en tant qu’équipe, comprenons le domaine. D’autre part, les tests de bout-en-bout ne nous disent rien quand à la qualité de notre code.
Ecrire des tests unitaires nous donne beaucoup de feedback sur la qualité du code, et les rouler nous permet de savoir si nous avons cassé des classes. Ceci ne nous donne pas une confidence complete que le système marche en totalité.
Les tests d’integration se trouvent au milieu.
Ne me comprenez pas mal, je ne veux pas diminuer l’apport des tests unitaires ici. Je veux toutefois porter le point que les tests d’acceptation sont généralement ceux qui nous informent plus sur la qualité externe du système.
Le point est que les tests d’acceptation ne sont pas des tests unitaires. Bob C. Martin (Uncle Bob) fait le point comme suit :
Les tests unitaires sont écrits par les programmeurs pour les programmeurs.
Ce sont des documents de design qui décrivent la structure de bas niveau du logiciel, et le comportement du code.
Je répète, l’audience des tests unitaires sont le programmeurs et non la business.
Les tests d’acceptation sont écrits par la business (ce qui pourrait vous inclure des fois, cher programmeur). Ce sont des documents formels de requis qui spécifient le comportement du système d’un point de vue business. L’audience de ces tests est la business et les programmeurs.
Il est souvent tentant d’essayer d’éliminer l’extra-travail en assumant que ces deux types de tests sont redondants. Malgré que c’est vrai que les tests unitaires et les tests d’acceptation testent souvent les memes choses, ils ne sont toutefois pas redondants du tout!
Donc non. Non. Ce n’est pas la même chose. Et ce n’est pas du travail en double. Pourquoi?
Premièrement, Malgré qu’ils testent souvent la meme chose, ils le font via des chemins et des mécanismes différents. Les tests unitaires s’enfoncent dans les entrailles du système en appelant des méthodes particulières de classes particulières. Les tests d’acceptation, d’autre part, invoquent le système de plus loin, au niveau de l’API ou encore au niveau du UI. Les chemins d’execution que ces tests prennent sont très différents.
Mais la vraie raison qu’ils ne sont pas redondants est que leur première fonction n’est pas de tester! Le fait que ce sont des tests est un incident. Les tests d’acceptation et les tests unitaires sont avant tout des documents, et deuxièmement des tests. Leur objectif principal est de documenter le design, la structure et le comportement du système. Le fait qu’ils vérifient automatiquement le design, le comportement et la structure est très utile, mais la Spécification est leur objectif premier!