https://codurance.com/2015/05/12/does-tdd-lead-to-good-design/
Malheureusement, elles ne permettent pas de répondre ou très indirectement à la question : Comment je peux développer et vérifier efficacement la solution à un problème donné (une règle métier, une interaction avec une base de donnée, etc.) ?
Pour appréhender au mieux l’approche que je vais proposer, il est préférable d’avoir deux pré requis.
Ce dernier est au centre de plusieurs architectures.
Permettre à une application d’être pilotée aussi bien par des utilisateurs que par des programmes, des tests automatisés ou des scripts batchs, et d’être développée et testée en isolation de ses éventuels systèmes d’exécution et bases de données. - Alistair Cockburn (Hexagonal Architecture ou Ports/Adapters Architecture)
L’élément clé d’une application ne réside pas dans sa base de données et les frameworks utilisés. Les use-cases d’une application sont l’élément central. - Robert C. Martin (Clean Architecture)
Pour explorer davantage les concepts et le lexique de ces architectures, je vous conseille ces articles :
Dans la suite, j’utiliserai le schéma ci-dessous pour mettre en avant les différentes parties utilisées :
Les flèches représentent le sens des dépendances, ce sont les côtés Adapters qui dépendent du centre Core qui détient les règles métiers et non l’inverse.
Pour lui un gros problème porte sur l’interprétation des gens de la propriété unitaire d’un test. En effet, un test unitaire doit pouvoir se lancer en isolation des autres, ce qui est résumé par : “si je crée cette classe alors elle doit être testée toute seule pour respecter la propriété”.
Cette vision nous éloigne d’une approche basée sur le comportement et c’est plutôt cela que l’on souhaite vérifier. C’est bien un test sur un comportement qui doit être isolé d’un autre.
Un autre problème, les développeurs/ses testent leurs détails d’implémentation. Du coup, ils écrivent beaucoup de tests, ce qui ralentit le développement et quand ils refactorent (activité qui consiste à changer l’implémentation sans changer le comportement d’un code) beaucoup de tests cassent. Cela engendre des abandons de TDD.
Alors qu’écrire ses tests via l’API publique de son code réduit le nombre de tests et rend plus productif, de plus le code devient plus simple à refactorer.
Pour résumer ces deux points donnent les avantages suivants :
Enfin, il recommande d’utiliser des architectures permettant d’isoler son domaine des frameworks ou autres technologies (exemple : accès à la base de données), comme l’architecture Ports/Adapters.
Conférence TDD, where did it all go wrong :
On peut extraire deux points d’attention qui se suivent dans l’article ci-dessus :
Si nous reprenons la pyramide des tests, on peut distinguer quatre grandes catégories :
La première catégorie me semble essentielle. Elle permet d’avoir une boucle de feedback des plus rapides sur le développement en cours et reste relativement simple à mettre en place.
Maintenant, mettons en évidence les points d’entrée et les parties vérifiées par chacune des catégories.
Les points d’entrée sont les Use Cases de l’application et avec les tests qui s’arrêtent aux frontières du Core avec l’utilisation d’une fausse implémentation d’un Adapter de droite (cf. les articles pour connaître leurs particularités).
Ils se focalisent sur la vérification de la bonne implémentation des règles métiers et de ce qui a de la valeur pour l’entreprise.
Articles associés :
Les points d’entrée sont les Use Cases de l’application et avec les tests qui s’arrêtent aux frontières du Core avec l’utilisation d’une fausse implémentation d’un Adapter de droite (cf. l’article pour connaître leurs particularités).
Ils se focalisent sur la vérification de la bonne implémentation des règles métiers et de ce qui a de la valeur pour l’entreprise.
À la différence des tests unitaires, ils émergent d'une autre manière et se focalisent sur la variété des possibles. Nous verrons un cas d’usage dans un article dédié.
Article associé :
Les points d’entrée sont les Adapters de l’application et avec les tests qui s’arrêtent à cette case.
Ils se focalisent sur la vérification de la bonne intégration avec un système tiers (ex. une base de données, une REST API, l’affichage des données pour un client, etc.), sans se préoccuper des règles métiers.
On fera en général un ou quelques cas passants et non-passants, si ces derniers existent.
Exemples :
Articles associés :
Les points d’entrée sont les Adapters de gauche de l’application (cf. l’article pour connaître leurs particularités) et avec les tests, orientés fonctionnels, qui ont pour but de traverser toutes les couches de l’application ; Adapters et Core en étant ou non connecté aux systèmes tiers (base de données, REST API, etc.).
Ils se focalisent sur la vérification du bon fonctionnement de l’ensemble du projet. On pourra par exemple faire un chemin critique de celui-ci.
Article associé :
Nous avons vu qu’il y avait deux grandes approches, mais elles ne répondent pas à certaines interrogations et laissent des délimitations floues de l’application.
En conjuguant, l’approche de Ian Cooper avec le principe d’inversion des dépendances porté par certaines architectures (Clean Architecture, Hexagonale Architecture), nous pouvons avoir des associations plus claires :
Pour terminer, on remarquera qu‘il n’y a pas de distinction entre front-end et back-end, cela pour mettre en avant que la démarche réalisée durant cette série d’articles est valable pour les deux mondes.
Annexe : https://www.stevefenton.co.uk/2013/05/my-unit-testing-epiphany/