Architecture
Bonnes pratiques
Design Pattern
hexagonale

Enocre une ressource sur l'archi hexa, ça fait pas de mal !


Partagé par Benoit GANTAUME
il y a 5 mois
18

Damien Palagi il y a 5 mois
Je l'ai vu il y a quelques semaines celle-ci, elle est au top !

J'aime ce type de pédagogie où l'on suit la réflexion du bonhomme étape par étape, plutôt que de te présenter "simplement le résultat final" en mode "c'est comme ça qu'il faut faire".
Sergio Mazzoleni il y a 5 mois
Présentation intéressante. Elle met en avant une série de choses que je faisais déjà intuitivement, mais ça m'a permis de mettre des mots sur certains concepts. Et je dis "intuitivement", mais ces pratiques résultent quand même de plusieurs mois d'essais/erreurs, cette présentation m'aurait fait gagner du temps si je l'avais vue plus tôt.
Bien écrire ses tests unitaires, c'est tout un art...
Mickael Hassine il y a 5 mois
En effet, le mock ne devrait être utilisé qu'en dernier recours. Mock une API, ok. Mock la moitié du code parce qu'on se sent obligé de le faire pour tester un bout de code, non. Si on se retrouve dans cette situation, c'est qu'on a pas bien respecté le SRP quelque part...
Romain Fallet il y a 5 mois
Hyper interessant, merci @Benoit. Je vois qu’il y a également pas mal de débats entre tester sur une vraie base de données et sur des équivalents « in memory ». Est-ce que certains ont des avis là-dessus ? Les pros in-memory avancent la rapidité d’exécution pour les tests fonctionnels mais avec l’approche évoquée dans cette conférence, le problème ne se pose pas.
xtrembaker il y a 5 mois
Vidéo intéressante, merci pour le partage. J’ajouterai que la notion de mock doit intervenir à un degré relatif en fonction du type de test, je m’explique. Selon moi il existe grossomodo 4 types différents de test (unitaire, intégration, fonctionnel, end to end). Dans chaque cas le scope du test et son objectif sont différents, et l’utilisation des mocks doit respectivement être décroissante. Dans le cas d’un test unitaire, 100% des dépendances doivent être mockées, alors que dans un test "end to end" ça serait plus proche du 0%. Bien entendu, en fonction des besoins / performances, pour réaliser les tests, on peut choisir librement d’utiliser des mocks, ou bien des implémentations en mémoire (pour les repos par exemple).

Typiquement, dans le cas des tests sur un controlleur, il est très fort probable qu’une même partie de code (un repo, ou un service) soit appelée à chaque fois dans chacun des tests. Dans ce cas, non seulement on test plusieurs fois la même partie de code (ce qui est inutile), mais en plus, si une partie des tests est lente (I/O), alors ceci va avoir un impact sur la durée globale de la suite de test.

Perso, pour contrer ce double problème, je réalise toujours des tests fonctionnels des repositories / services de manière isolés (pour m’assurer de leur comportement), ce qui me permet de les mocker sans craintes lors de mes tests de controlleur.
Marc Bouvier il y a 5 mois
Sur exactement le même sujet, Victor Rentea (Bucharest Software community) nous a fait une présentation montée sur ressorts.

www.youtube.com/...
Romain Fallet il y a 5 mois - modifié il y a 5 mois
@xtrembaker J'avoue ne pas bien faire la distinction que tu fais entre test unitaire et test fonctionnel/d'intégration. Pour moi la notion de test unitaire est ambigüe, de quelle unité parle-t-on ?

Dans le cas expliqué dans la vidéo, il n'y a pas de tests unitaires à proprement parler puisque les tests infrastructure/application sont forcément des tests d'intégrations (application du principe "don't mock what you don't own") et les tests de la couche métier sont forcément des tests fonctionnels puisque l'on teste les cas d'usage.

Et il n'y en a pas d'autre (à part les tests de bout en bout) puisqu'il indique qu'on ne doit tester que les fonctions/méthodes publiques (tout le reste c'est de l'implémentation et on ne teste pas l'implémentation).

Pour moi tout ce qui n'est pas un test de bout en bout est un test unitaire finalement, et on change simplement l'unité que l'on veut tester en fonction du contexte (infrastructure, métier, application).

Est-ce que d'autres personnes font aussi cette distinction ?
xtrembaker il y a 5 mois
@Romain Fallet

Très bonne question, et pour être tout a fait honnête, il y a beaucoup de débat sur la toile sur la définition de chaque terme.
Voici un lien du site de Martin Fowler qui tente de regrouper l’ensemble des tests (martinfowler.com/testing), leurs définitions et leurs usages.

De mon point de vue, en tant que Backend développeur:

Test unitaire: On test uniquement la méthode d’une classe. Si la méthode est dites "pure", on s’assure que pour une entrée X, on a toujours la sortie Y (exemple, une méthode "addition" - si on a en entrée a = 1, et b = 2, alors la sortie doit être 3). Dans le cas où cette méthode fait appel a des services, ces derniers doivent être mocké, on veut simplement s’assurer que le workflow est correct. Si la méthode contient des conditions, chaque cas de condition doit être testé pour s’assurer que le comportement attendu dans chaque est correct.

Test d’intégration: Perso, je mets dans cette catégorie les tests de repositories. Je veux m’assurer que mes requêtes sont correctement formés et qu’elles me retournent les bons résultats si j’ai des conditions pour la création du query builder notamment. En général, je ne mock rien dans ce type de cas de tests.

Test fonctionnel: Il s’agit de tester de manière plus globale une brique fonctionnelle (par exemple, dans le cas d’un service qui serait dédié a la création d’une nouvel utilisateur, on s’assure que les données sont bien enregistrées en base, et que l’on a bien envoyé un email de bienvenue). Bien entendu, on peut mocker certaines parties (comme l’envoi du mail par exemple, puisque ceci est fortement lié à la partie infrastructure, on veut juste s’assurer que l’on est bien passé par le service d’envoi du mail - le fait de l’avoir reçu ou non, ce n’est pas notre responsabilité). Les tests de service complexe rentre selon moi dans cette catégorie.

Test end-to-end: Je vais tester dans cette catégorie tous les composants qui servent de facade a mon application (un controlleur, une commande en ligne, par exemple). Tout comme les tests fonctionnels, certains services peuvent être mockés pour les besoins du tests, mais dans l’idée il en faut le moins possible.

Tout ceci n’est pas à prendre comme argent comptant, c’est la vision que j’en ai à mesure de lire des articles sur ce sujet - et c’est un sujet très vaste...
Romain Graziani il y a 5 mois - modifié il y a 5 mois
@Romain Fallet

"Est-ce que d'autres personnes font aussi cette distinction ?"

Personnellement , j'adopte cette définition pour les tests unitaires:
- mono-langage (pas Java + sql par ex)
- mono-couche (pas de métier + I/O par ex)
- répétable (toujours le même résultat)
- rapide (on est en bas de la pyramide des tests)

Tous les tests qui ne répondent pas à cette définition sont des tests d'intégration.
Je n'oppose pas tests fonctionnels et tests unitaires, selon moi on peut trouver des tests fonctionnels unitaires et fonctionnels d'intégration.
La notion de end-to-end est selon moi "variable". Dans des SI suffisamment conséquents, ce qui peu apparaitre à un certain moment comme test e2e (on est au limites du "sous-système" testé), peut dans un cadre plus large être un "simple" test d'intégration (le système est plus large). Cela dépend de la responsabilité de l'équipe en charge / des limites du SI accessible sur un environnement donné.
Geoffrey Cousin il y a 5 mois
Excellent vidéo. Je ne fais pas encore de TDD, mais elle me pousse à essayer.

Je suis d'accord avec @xtrembaker mais je suis peut-être influencé par mon expérience de backend
Julien Sere il y a 5 mois
Je crois que c'est la meilleure démonstration d'écriture de tests logiciels que j'ai vu en français. Il me semble que le présentateur a clairement saisit les enjeux autour des tests et applique de façon très pragmatique les bonnes pratiques. Je recommande clairement cette vidéo à tous ceux qui se posent des questions autour des tests, vous en apprendrez beaucoup ! le plus dur est sans doute de réaliser à quel point les arguments avancés sont pertinent
dav il y a 5 mois
xtrembaker , je pense tout comme Romain Fallet que ton interprétation du test unitaire est en contradiction avec la vidéo. Regarde la vidéo de Ian Cooper conseillée par Damien Palagi. Un test unitaire est un test d'une fonctionnalité. Donc il peut y avoir plusieurs collaborateurs et méthodes testées par ce test. Unitaire = isolé des autres tests.
xtrembaker il y a 5 mois
@dav Merci pour la vidéo de Ian Cooper, je viens de la regarder et c’est effectivement intéressant.
Cependant je m’interroge sur un point. Il est dit qu’un test unitaire doit se focaliser sur un comportement et non sur la méthode d’une classe. Toutefois, le nombre de bug que j’ai pu éviter, ou que j’ai corrigé, simplement en ajoutant des tests sur des méthodes de classe un peu tricky (calcul, ou conversion par exemple) est innombrable. Si je ne suis pas censé écrire de tests sur la méthode d’une classe, je ne vois pas comment je peux m’assurer qu’elle retourne bien le résultat attendu.
dav il y a 5 mois - modifié il y a 5 mois
Bonne remarque :) Je ne suis pas du tout expert sur le sujet, donc ma réponse est à prendre avec des pincettes. Pour moi c'est une question de nuance. Certaines classes n'auront aucun TU directement associés, car elles seront complétement couvertes par d'autres tests. D'autres seront complètement couvertes par des tests spécifiques si leur fonctionnalité est complexe.
Mais je manque d'arguments et de ressources pour détailler cette nuance :/
Julien Sere il y a 5 mois
@xtrembaker, lorsque j'ai une méthode un peu tricky comme tu dis, c'est surrement un élément important/complexe de ton business. Je te recommande alors de sortir cet élément dans une classe distincte dédié à l'implémentation de cette algo. ca te permet donc de dégager une partie "complexe" de ta classe mère, de sans doute mieux respecter le principe de single responsability
Ca te permettra de faire peut etre apparaitre mieux dans ton code un concept métier (si méthode compliqué c'est bien que c'est un point sensible métier normalement)
En le mettant dans une classe dédié, tu pourras aussi le remplacer plus simplement (par exemple ca devient facile de remplacer l'appel de cette classe dédié par une interface et ca ouvre la porte à la possibilité de switcher facilement d'implémentation, imagine que tu as une idée pour améliorer l'algo en question ou améliorer sa vitesse, bim ca devient possible facilement par le fait que tu ai extrait l'algo dans une classe dédié)
Pour ajouter un commentaire, tu dois te connecter ou créer un compte.
Le cursus Artisan Développeur v1.1
Accéder à l'épisode
C'est L'histoire D'un Mec Qui Code Un Truc En 2h
Accéder à l'épisode
Comment foirer son projet sans se faire choper avec Frédéric Leguédois
Accéder à l'épisode
Découvrir de nouvelles technos avec Matthieu Segret
Accéder à l'épisode
Principe #12 Amélioration Continue
Accéder à l'épisode
Artisan Développeur utilise des cookies afin de t'offrir les meilleurs services. En poursuivant ta navigation, tu acceptes l’utilisation de cookies. En savoir plus