- Nouveau
- Tendances
- Classement
-
Tagsnewsletternewsletter46devdev45bonnes-pratiquesBonnes pratiques43phpPHP36programmationprogrammation34veilleVeille15teletravailTélétravail15architectureArchitecture13tddTDD13agiliteAgilité12javascriptJavaScript12design-patternDesign Pattern12codeCode11devopsDevOps10laravelLaravel9conferenceConférence8carriereCarrière8front-endfront-end7retour-d-experienceRetour d'experience7formationFormation6entreprenariatEntreprenariat6gitGit6cultureCulture6clean-codeClean Code6youtubeYoutube6craftCraft5refactoringrefactoring5videoVidéo5interviewinterview5organisationOrganisation5podcastPodcast5code-legacyCode Legacy4compagnonCompagnon4dddDDD4testingTesting4freelancingFreelancing4tech-leadTech Lead4optimisationOptimisation4javaJava3pythonPython3iaIA3humourHumour3reactReact3ethiqueEthique3emploiEmploi3ecologieEcologie3reconversionReconversion3debutantDébutant3remoteremote3cqrsCQRS3covid-19Covid-193securiteSécurité3retrospectiveRetrospective3clean-architectureClean Architecture3ci-cdCI/CD3vue-jsvue.js3blogBlog3architecture-hexagonaleArchitecture Hexagonale3rustrust3performancesperformances3nodejsNodeJS3programmation-fonctionnelleProgrammation fonctionnelle3productivteproductivté3slackSlack2donnees-personnellesDonnées personnelles2ecosystemeEcosystème2pair-programmingPair programming2evenementÉvènement2personal-brandingpersonal branding2produitProduit2gestion-du-tempsGestion du temps2changelogChangelog2cercleCercle2green-itGreen IT2hexagonalehexagonale2vscodevscode2pooPOO2webWeb2tinydbTinyDB1algorithmealgorithme1alignementAlignement1originesOrigines1dbDB1vie-priveeVie privée1androidAndroid1ctoCTO1apiAPI1csscss1restREST1pedagogiePédagogie1coup-de-gueuleCoup de gueule1vision-systemiqueVision systémique1prodprod1atddatdd1audioAudio1autonomieAutonomie1visualstudiovisualstudio1cloudCloud1vite-jsvite.js1slow-techSlow.tech1avenirAvenir1bddbdd1chansonChanson1bffBFF1blazorblazor1ports-and-adaptersPorts and Adapters1queerQueer1goGo1graphqlGraphQL1hibernatehibernate1hommageHommage1net.NET1mvcmvc1ideide1inclusionInclusion1ingenieurieIngénieurie1mutation-testingMutation testing1minimalismeMinimalisme1systeme-de-queueSystème de queue1jobjob1langagelangage1sqlSQL1licorneLicorne1livelive1lowtechLowTech1maisonMaison1buildbuild1theorie-des-contraintesThéorie des contraintes1devtoolDevTool1diversiteDiversité1dockerdocker1dojoDojo1open-sourceOpen Source1onlineonline1energieEnergie1entrainementEntrainement1thematuredevTheMatureDev1entretienentretien1entretien-d-embaucheEntretien d'embauche1event-sourcingEvent sourcing1extreme-programmingeXtreme Programming1flowflow1flowconFlowcon1react-nativeReact-Native1springbootspringboot1testtest1microsoftmicrosoft1
- Mes favoris
- Recevoir par email
- Partager un lien
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 presque 4 ans
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".
Bien écrire ses tests unitaires, c'est tout un art...
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.
www.youtube.com/...
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 ?
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...
"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é.
Je suis d'accord avec @xtrembaker mais je suis peut-être influencé par mon expérience de backend
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.
Mais je manque d'arguments et de ressources pour détailler cette nuance :/
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é)