Description
Notion centrale et a priori de base dans le parcours de dev, discutons un peu des écarts de visions pouvant exister sur les tests unitaires.
Hébergé par Ausha. Visitez ausha.co/politique-de-confidentialite pour plus d'informations.




Description
Notion centrale et a priori de base dans le parcours de dev, discutons un peu des écarts de visions pouvant exister sur les tests unitaires.
Hébergé par Ausha. Visitez ausha.co/politique-de-confidentialite pour plus d'informations.
Transcription
Bonjour à tous et bienvenue sur ce nouvel épisode du podcast PunkinDev. Les tests. Les tests sont un passage incontournable de l'activité de dev. Il faut forcément tester, de quelque manière que ce soit. Certains font des tests automatisés, d'autres font des tests de qualification, ou bien des tests de charge, des tests de non-régression, et bien d'autres typologies de tests encore. Quand on parle de code, on associe souvent au développement la rédaction de tests unitaires associés. Combien de fois m'a-t-on demandé un chiffrage R plus TU, à savoir réalisation plus TU, test unitaire ? Mettons aujourd'hui de côté la pertinence de ce genre de demande. Après la réalisation, il reste tout de même cette notion de test unitaire. C'est quelque chose dont on parle très souvent, sans forcément être très clair sur ce qu'on met dedans. C'est lors d'une discussion à ce sujet, pendant un after du Mug à Lyon, que j'ai pris conscience que ma définition du test unitaire avait grandement évolué au fil des ans. Tentons aujourd'hui de répondre à cette simple question. Mais en fait, c'est quoi un test unitaire ? Prenons d'abord le mot test Qu'est-ce qu'on entend par test Pour donner une définition un petit peu simple, on pourrait dire qu'il s'agit juste d'une procédure visant à valider le bon fonctionnement d'une certaine quantité de code. que le comportement codé correspond bien à celui attendu. Par abus de langage, on pourrait simplement parler de vérification. Mais il y a ensuite la notion d'unitaire. Qu'est-ce qu'on entend par unitaire ? Pour moi ici, l'idée c'est d'avoir un test qu'on peut considérer comme petit et léger, afin qu'il soit automatisable et réexécutable à volonté, sans passer des heures à attendre que la machine termine le travail. En résumé, un test unitaire doit valider le bon fonctionnement du code, mais de manière rapide. Mais alors, pourquoi parle-t-on d'unitaire ? Qu'est-ce que c'est une unité ? Et puis une unité de quoi ? Sur quel périmètre est-ce qu'on choisit de travailler ? Et c'est là que le concept devient un peu plus vaporeux et beaucoup plus sujet à interprétation qu'il n'en a l'air. Pour mes tout premiers tests unitaires, il y a fort longtemps, je considérais que l'unité, c'était la fonction ou la méthode. Une méthode égale un test. Avec mon recul actuel, bien que discutable, je trouve que cette approche a au moins le mérite d'exister. Elle permet, même à un niveau assez faible, de disposer tout de même de tests, et donc d'une base sur laquelle travailler. Je trouve ça plus simple de faire progresser une pratique existante que de devoir initier une pratique à partir de rien. Et au final, je préfère avoir un dev qui débute dans l'écriture de ses tests, plutôt qu'un dev qui prétend pouvoir s'en passer. Là où il y a une démarche d'automatisation, j'estime qu'il y a une démarche d'amélioration, et qu'on peut avancer. Mais on ne va pas se voiler la face. Il va y en avoir du chemin à parcourir, avant que ces petits tests-là ne jouent pleinement leur rôle. C'est donc avec cette approche quelque peu naïve, que j'ai commencé à écrire mes premiers tests unitaires, et que j'ai rapidement rencontré des problèmes. parfois tout simple, mais qui me bloquait totalement à cette époque. Le premier, pour ne citer que lui, particulièrement symptomatique. Comment faire pour tester mes méthodes privées ? Ces méthodes contenant des algos importants, je voulais absolument les mettre sous test, mais en même temps, les méthodes en question n'étaient pas accessibles dans mon projet de test, et je trouvais assez discutable de devoir modifier mon code de prod simplement pour pouvoir le mettre sous test. Je vais me permettre une petite pause et un petit focus sur cette réflexion. Le fait de devoir modifier le code pour pouvoir le mettre sous test. J'imaginais pas du tout à ce moment là les implications potentielles d'une telle question. On touche ici une notion fondamentale sur laquelle je vais revenir assez vite. Si je reviens à ma petite histoire donc, après ces quelques difficultés, et faute d'encadrement de coaching efficace, j'étais bloqué. Et j'ai été un peu contraint, contre mon gré. de mettre de côté mes envies de tests unitaires. Franchir tout seul cette marche était trop difficile. J'aurais eu un lead dev, un coach, un formateur, juste un dev expérimenté qui m'aurait montré le chemin, qui m'aurait donné les bons sites, les bons bouquins à lire. J'aurais peut-être pu m'en sortir, mais là j'étais vraiment seul. Le temps passant, j'ai longuement erré, et j'ai fini par expérimenter des choses. bien souvent en coding dojo ou sur des projets simples. Les projets Legacy font encore aujourd'hui figure de cas particuliers, tant ils peuvent parfois représenter un défi colossal quand on veut leur greffer des tests unitaires. Au final, c'est surtout donc sur de nouveaux projets, et avec le bon entourage, que j'ai pu avoir l'évolution la plus intéressante. J'ai pu faire évoluer ma vision du test unitaire avec une relation 1-1 avec l'implémentation, cette vision d'une méthode, un test. Et petit à petit, j'ai commencé à écrire des tests qui étaient moins en relation avec le code, et plus en relation avec des comportements métiers. À essayer à chaque fois, plutôt que de tester mon implémentation, tester un comportement métier. Ça peut avoir l'air de rien, dit comme ça, mais cette posture change absolument tout. On ne va plus essayer de valider le code, comme je le donnais dans ma définition au départ. On va valider un comportement métier, une valeur business. Le fait de se mettre... dans cette optique, de valider du métier avant de valider du code, ça va avoir un impact profond. On va être obligé de poser beaucoup plus de questions au métier, au sachant métier, au PO. Et de ce comportement-là va découler un changement de vision de ces mêmes personnes vis-à-vis des développeurs. Le dev, en général, bien souvent, dans beaucoup d'équipes, est considéré comme celui qui parle au code, qui parle à son écran. et qui ne s'intéresse pas au métier, qui ne comprend pas la valeur business. Donc on ne lui demande pas de s'y intéresser. Et je ne pense pas que ce soit une bonne dynamique. A l'inverse, si vous commencez à écrire des tests purement métier, à valider des cas, vous allez devoir poser les questions. Comment on traite cette donnée ? Comment on traite ce cas-là ? Quel est le processus pour passer de tel cas à tel cas ? Et le fait de poser ces questions, vraiment, ça va changer l'approche et le regard que le reste de l'équipe porte sur votre travail. Moi je trouve ça vraiment très très important. Ça change beaucoup de choses. Mais ça n'en change pas que là. Ça en change aussi au niveau du code. Parce que mine de rien, quand on a des tests unitaires automatisables, qui valident vraiment une valeur métier, on peut retransformer l'implémentation. Il n'y a pas de problème. On peut faire du refacto. On peut réécrire des blocs quand c'est difficile à maintenir. Le test unitaire est là pour valider que le fonctionnel, le fonctionnement global, est toujours bon. Un effet de bord de cette approche est qu'aujourd'hui je ne me pose plus la question, par exemple, comment tester mes méthodes privées. Privé au public, mon test s'en fiche et il va valider un comportement, pas une implémentation. De cette manière, mon implémentation elle pourra évoluer, être mise au propre, voire être totalement réécrite si besoin. Je n'aurai pas besoin de reprendre mes tests, ça ne va pas les casser. De ce point de vue, sur mes expériences d'origine, j'avais raison. de ne pas vouloir modifier mon code pour le mettre sous test. Ça aurait été une mauvaise solution à un vrai problème. En revanche, là où j'avais tort, c'est que le code doit être conçu pour pouvoir être testé simplement. Une des meilleures façons de rendre notre code facilement testable, c'est de s'occuper d'abord de l'aspect métier, du code, du traitement métier pur. On va mettre du test là-dessus, on va faire notre implémentation, et ensuite seulement, on travaillera sur toute la... tuyauterie technique, les accès base de données, les accès réseau, toutes ces choses-là. Mais d'abord, la valeur métier, par le test, par le code. Avec tout ce qu'on vient de voir, je pense qu'on peut s'essayer à une nouvelle définition du test unitaire. Aujourd'hui, quand je dis unitaire, personnellement, j'entends la plus petite unité de traitement métier possible. Un test unitaire ne va donc plus couvrir une fonction de méthode, mais un cas métier. Une seule et unique typologie. de données, avec un entrant reproductible et une sortie systématiquement prévisible. Pour résumer, je dirais donc qu'un test unitaire, ça va être un test simple qui ne couvre qu'un seul cas métier. Il doit être rapide d'exécution pour s'intégrer facilement dans un process d'automatisation. Et enfin, comme je l'ai déjà dit plusieurs fois, il ne doit tester qu'un comportement métier, jamais une implémentation. Mon code doit rester libre d'évoluer sans risque de casser la logique métier. Et ça, Seul des tests avec une orientation purement métier pourra vous y amener. Il reste encore la question de comment produire de tels tests, et ce sera pour de prochains épisodes dans lesquels je parlerai tour à tour de TDD, d'inversant de dépendance, de mock, de fake et tout un tas d'autres techniques qui permettent d'arriver là. Voilà ma contribution sur la notion de test unitaire. Comme vous le voyez, c'est pas si simple que ça en a l'air. J'espère que cet épisode vous aura plu, qu'il vous donnera envie de vous y mettre ou d'approfondir vos connaissances sur le testing. Pour vous entraîner, je vous invite vraiment à participer au coding dojo proche de chez vous. On progresse toujours mieux à plusieurs. A bientôt pour un prochain épisode. D'ici là, dites-les bien. Vous délire ?
Description
Notion centrale et a priori de base dans le parcours de dev, discutons un peu des écarts de visions pouvant exister sur les tests unitaires.
Hébergé par Ausha. Visitez ausha.co/politique-de-confidentialite pour plus d'informations.
Transcription
Bonjour à tous et bienvenue sur ce nouvel épisode du podcast PunkinDev. Les tests. Les tests sont un passage incontournable de l'activité de dev. Il faut forcément tester, de quelque manière que ce soit. Certains font des tests automatisés, d'autres font des tests de qualification, ou bien des tests de charge, des tests de non-régression, et bien d'autres typologies de tests encore. Quand on parle de code, on associe souvent au développement la rédaction de tests unitaires associés. Combien de fois m'a-t-on demandé un chiffrage R plus TU, à savoir réalisation plus TU, test unitaire ? Mettons aujourd'hui de côté la pertinence de ce genre de demande. Après la réalisation, il reste tout de même cette notion de test unitaire. C'est quelque chose dont on parle très souvent, sans forcément être très clair sur ce qu'on met dedans. C'est lors d'une discussion à ce sujet, pendant un after du Mug à Lyon, que j'ai pris conscience que ma définition du test unitaire avait grandement évolué au fil des ans. Tentons aujourd'hui de répondre à cette simple question. Mais en fait, c'est quoi un test unitaire ? Prenons d'abord le mot test Qu'est-ce qu'on entend par test Pour donner une définition un petit peu simple, on pourrait dire qu'il s'agit juste d'une procédure visant à valider le bon fonctionnement d'une certaine quantité de code. que le comportement codé correspond bien à celui attendu. Par abus de langage, on pourrait simplement parler de vérification. Mais il y a ensuite la notion d'unitaire. Qu'est-ce qu'on entend par unitaire ? Pour moi ici, l'idée c'est d'avoir un test qu'on peut considérer comme petit et léger, afin qu'il soit automatisable et réexécutable à volonté, sans passer des heures à attendre que la machine termine le travail. En résumé, un test unitaire doit valider le bon fonctionnement du code, mais de manière rapide. Mais alors, pourquoi parle-t-on d'unitaire ? Qu'est-ce que c'est une unité ? Et puis une unité de quoi ? Sur quel périmètre est-ce qu'on choisit de travailler ? Et c'est là que le concept devient un peu plus vaporeux et beaucoup plus sujet à interprétation qu'il n'en a l'air. Pour mes tout premiers tests unitaires, il y a fort longtemps, je considérais que l'unité, c'était la fonction ou la méthode. Une méthode égale un test. Avec mon recul actuel, bien que discutable, je trouve que cette approche a au moins le mérite d'exister. Elle permet, même à un niveau assez faible, de disposer tout de même de tests, et donc d'une base sur laquelle travailler. Je trouve ça plus simple de faire progresser une pratique existante que de devoir initier une pratique à partir de rien. Et au final, je préfère avoir un dev qui débute dans l'écriture de ses tests, plutôt qu'un dev qui prétend pouvoir s'en passer. Là où il y a une démarche d'automatisation, j'estime qu'il y a une démarche d'amélioration, et qu'on peut avancer. Mais on ne va pas se voiler la face. Il va y en avoir du chemin à parcourir, avant que ces petits tests-là ne jouent pleinement leur rôle. C'est donc avec cette approche quelque peu naïve, que j'ai commencé à écrire mes premiers tests unitaires, et que j'ai rapidement rencontré des problèmes. parfois tout simple, mais qui me bloquait totalement à cette époque. Le premier, pour ne citer que lui, particulièrement symptomatique. Comment faire pour tester mes méthodes privées ? Ces méthodes contenant des algos importants, je voulais absolument les mettre sous test, mais en même temps, les méthodes en question n'étaient pas accessibles dans mon projet de test, et je trouvais assez discutable de devoir modifier mon code de prod simplement pour pouvoir le mettre sous test. Je vais me permettre une petite pause et un petit focus sur cette réflexion. Le fait de devoir modifier le code pour pouvoir le mettre sous test. J'imaginais pas du tout à ce moment là les implications potentielles d'une telle question. On touche ici une notion fondamentale sur laquelle je vais revenir assez vite. Si je reviens à ma petite histoire donc, après ces quelques difficultés, et faute d'encadrement de coaching efficace, j'étais bloqué. Et j'ai été un peu contraint, contre mon gré. de mettre de côté mes envies de tests unitaires. Franchir tout seul cette marche était trop difficile. J'aurais eu un lead dev, un coach, un formateur, juste un dev expérimenté qui m'aurait montré le chemin, qui m'aurait donné les bons sites, les bons bouquins à lire. J'aurais peut-être pu m'en sortir, mais là j'étais vraiment seul. Le temps passant, j'ai longuement erré, et j'ai fini par expérimenter des choses. bien souvent en coding dojo ou sur des projets simples. Les projets Legacy font encore aujourd'hui figure de cas particuliers, tant ils peuvent parfois représenter un défi colossal quand on veut leur greffer des tests unitaires. Au final, c'est surtout donc sur de nouveaux projets, et avec le bon entourage, que j'ai pu avoir l'évolution la plus intéressante. J'ai pu faire évoluer ma vision du test unitaire avec une relation 1-1 avec l'implémentation, cette vision d'une méthode, un test. Et petit à petit, j'ai commencé à écrire des tests qui étaient moins en relation avec le code, et plus en relation avec des comportements métiers. À essayer à chaque fois, plutôt que de tester mon implémentation, tester un comportement métier. Ça peut avoir l'air de rien, dit comme ça, mais cette posture change absolument tout. On ne va plus essayer de valider le code, comme je le donnais dans ma définition au départ. On va valider un comportement métier, une valeur business. Le fait de se mettre... dans cette optique, de valider du métier avant de valider du code, ça va avoir un impact profond. On va être obligé de poser beaucoup plus de questions au métier, au sachant métier, au PO. Et de ce comportement-là va découler un changement de vision de ces mêmes personnes vis-à-vis des développeurs. Le dev, en général, bien souvent, dans beaucoup d'équipes, est considéré comme celui qui parle au code, qui parle à son écran. et qui ne s'intéresse pas au métier, qui ne comprend pas la valeur business. Donc on ne lui demande pas de s'y intéresser. Et je ne pense pas que ce soit une bonne dynamique. A l'inverse, si vous commencez à écrire des tests purement métier, à valider des cas, vous allez devoir poser les questions. Comment on traite cette donnée ? Comment on traite ce cas-là ? Quel est le processus pour passer de tel cas à tel cas ? Et le fait de poser ces questions, vraiment, ça va changer l'approche et le regard que le reste de l'équipe porte sur votre travail. Moi je trouve ça vraiment très très important. Ça change beaucoup de choses. Mais ça n'en change pas que là. Ça en change aussi au niveau du code. Parce que mine de rien, quand on a des tests unitaires automatisables, qui valident vraiment une valeur métier, on peut retransformer l'implémentation. Il n'y a pas de problème. On peut faire du refacto. On peut réécrire des blocs quand c'est difficile à maintenir. Le test unitaire est là pour valider que le fonctionnel, le fonctionnement global, est toujours bon. Un effet de bord de cette approche est qu'aujourd'hui je ne me pose plus la question, par exemple, comment tester mes méthodes privées. Privé au public, mon test s'en fiche et il va valider un comportement, pas une implémentation. De cette manière, mon implémentation elle pourra évoluer, être mise au propre, voire être totalement réécrite si besoin. Je n'aurai pas besoin de reprendre mes tests, ça ne va pas les casser. De ce point de vue, sur mes expériences d'origine, j'avais raison. de ne pas vouloir modifier mon code pour le mettre sous test. Ça aurait été une mauvaise solution à un vrai problème. En revanche, là où j'avais tort, c'est que le code doit être conçu pour pouvoir être testé simplement. Une des meilleures façons de rendre notre code facilement testable, c'est de s'occuper d'abord de l'aspect métier, du code, du traitement métier pur. On va mettre du test là-dessus, on va faire notre implémentation, et ensuite seulement, on travaillera sur toute la... tuyauterie technique, les accès base de données, les accès réseau, toutes ces choses-là. Mais d'abord, la valeur métier, par le test, par le code. Avec tout ce qu'on vient de voir, je pense qu'on peut s'essayer à une nouvelle définition du test unitaire. Aujourd'hui, quand je dis unitaire, personnellement, j'entends la plus petite unité de traitement métier possible. Un test unitaire ne va donc plus couvrir une fonction de méthode, mais un cas métier. Une seule et unique typologie. de données, avec un entrant reproductible et une sortie systématiquement prévisible. Pour résumer, je dirais donc qu'un test unitaire, ça va être un test simple qui ne couvre qu'un seul cas métier. Il doit être rapide d'exécution pour s'intégrer facilement dans un process d'automatisation. Et enfin, comme je l'ai déjà dit plusieurs fois, il ne doit tester qu'un comportement métier, jamais une implémentation. Mon code doit rester libre d'évoluer sans risque de casser la logique métier. Et ça, Seul des tests avec une orientation purement métier pourra vous y amener. Il reste encore la question de comment produire de tels tests, et ce sera pour de prochains épisodes dans lesquels je parlerai tour à tour de TDD, d'inversant de dépendance, de mock, de fake et tout un tas d'autres techniques qui permettent d'arriver là. Voilà ma contribution sur la notion de test unitaire. Comme vous le voyez, c'est pas si simple que ça en a l'air. J'espère que cet épisode vous aura plu, qu'il vous donnera envie de vous y mettre ou d'approfondir vos connaissances sur le testing. Pour vous entraîner, je vous invite vraiment à participer au coding dojo proche de chez vous. On progresse toujours mieux à plusieurs. A bientôt pour un prochain épisode. D'ici là, dites-les bien. Vous délire ?
Share
Embed
You may also like
Description
Notion centrale et a priori de base dans le parcours de dev, discutons un peu des écarts de visions pouvant exister sur les tests unitaires.
Hébergé par Ausha. Visitez ausha.co/politique-de-confidentialite pour plus d'informations.
Transcription
Bonjour à tous et bienvenue sur ce nouvel épisode du podcast PunkinDev. Les tests. Les tests sont un passage incontournable de l'activité de dev. Il faut forcément tester, de quelque manière que ce soit. Certains font des tests automatisés, d'autres font des tests de qualification, ou bien des tests de charge, des tests de non-régression, et bien d'autres typologies de tests encore. Quand on parle de code, on associe souvent au développement la rédaction de tests unitaires associés. Combien de fois m'a-t-on demandé un chiffrage R plus TU, à savoir réalisation plus TU, test unitaire ? Mettons aujourd'hui de côté la pertinence de ce genre de demande. Après la réalisation, il reste tout de même cette notion de test unitaire. C'est quelque chose dont on parle très souvent, sans forcément être très clair sur ce qu'on met dedans. C'est lors d'une discussion à ce sujet, pendant un after du Mug à Lyon, que j'ai pris conscience que ma définition du test unitaire avait grandement évolué au fil des ans. Tentons aujourd'hui de répondre à cette simple question. Mais en fait, c'est quoi un test unitaire ? Prenons d'abord le mot test Qu'est-ce qu'on entend par test Pour donner une définition un petit peu simple, on pourrait dire qu'il s'agit juste d'une procédure visant à valider le bon fonctionnement d'une certaine quantité de code. que le comportement codé correspond bien à celui attendu. Par abus de langage, on pourrait simplement parler de vérification. Mais il y a ensuite la notion d'unitaire. Qu'est-ce qu'on entend par unitaire ? Pour moi ici, l'idée c'est d'avoir un test qu'on peut considérer comme petit et léger, afin qu'il soit automatisable et réexécutable à volonté, sans passer des heures à attendre que la machine termine le travail. En résumé, un test unitaire doit valider le bon fonctionnement du code, mais de manière rapide. Mais alors, pourquoi parle-t-on d'unitaire ? Qu'est-ce que c'est une unité ? Et puis une unité de quoi ? Sur quel périmètre est-ce qu'on choisit de travailler ? Et c'est là que le concept devient un peu plus vaporeux et beaucoup plus sujet à interprétation qu'il n'en a l'air. Pour mes tout premiers tests unitaires, il y a fort longtemps, je considérais que l'unité, c'était la fonction ou la méthode. Une méthode égale un test. Avec mon recul actuel, bien que discutable, je trouve que cette approche a au moins le mérite d'exister. Elle permet, même à un niveau assez faible, de disposer tout de même de tests, et donc d'une base sur laquelle travailler. Je trouve ça plus simple de faire progresser une pratique existante que de devoir initier une pratique à partir de rien. Et au final, je préfère avoir un dev qui débute dans l'écriture de ses tests, plutôt qu'un dev qui prétend pouvoir s'en passer. Là où il y a une démarche d'automatisation, j'estime qu'il y a une démarche d'amélioration, et qu'on peut avancer. Mais on ne va pas se voiler la face. Il va y en avoir du chemin à parcourir, avant que ces petits tests-là ne jouent pleinement leur rôle. C'est donc avec cette approche quelque peu naïve, que j'ai commencé à écrire mes premiers tests unitaires, et que j'ai rapidement rencontré des problèmes. parfois tout simple, mais qui me bloquait totalement à cette époque. Le premier, pour ne citer que lui, particulièrement symptomatique. Comment faire pour tester mes méthodes privées ? Ces méthodes contenant des algos importants, je voulais absolument les mettre sous test, mais en même temps, les méthodes en question n'étaient pas accessibles dans mon projet de test, et je trouvais assez discutable de devoir modifier mon code de prod simplement pour pouvoir le mettre sous test. Je vais me permettre une petite pause et un petit focus sur cette réflexion. Le fait de devoir modifier le code pour pouvoir le mettre sous test. J'imaginais pas du tout à ce moment là les implications potentielles d'une telle question. On touche ici une notion fondamentale sur laquelle je vais revenir assez vite. Si je reviens à ma petite histoire donc, après ces quelques difficultés, et faute d'encadrement de coaching efficace, j'étais bloqué. Et j'ai été un peu contraint, contre mon gré. de mettre de côté mes envies de tests unitaires. Franchir tout seul cette marche était trop difficile. J'aurais eu un lead dev, un coach, un formateur, juste un dev expérimenté qui m'aurait montré le chemin, qui m'aurait donné les bons sites, les bons bouquins à lire. J'aurais peut-être pu m'en sortir, mais là j'étais vraiment seul. Le temps passant, j'ai longuement erré, et j'ai fini par expérimenter des choses. bien souvent en coding dojo ou sur des projets simples. Les projets Legacy font encore aujourd'hui figure de cas particuliers, tant ils peuvent parfois représenter un défi colossal quand on veut leur greffer des tests unitaires. Au final, c'est surtout donc sur de nouveaux projets, et avec le bon entourage, que j'ai pu avoir l'évolution la plus intéressante. J'ai pu faire évoluer ma vision du test unitaire avec une relation 1-1 avec l'implémentation, cette vision d'une méthode, un test. Et petit à petit, j'ai commencé à écrire des tests qui étaient moins en relation avec le code, et plus en relation avec des comportements métiers. À essayer à chaque fois, plutôt que de tester mon implémentation, tester un comportement métier. Ça peut avoir l'air de rien, dit comme ça, mais cette posture change absolument tout. On ne va plus essayer de valider le code, comme je le donnais dans ma définition au départ. On va valider un comportement métier, une valeur business. Le fait de se mettre... dans cette optique, de valider du métier avant de valider du code, ça va avoir un impact profond. On va être obligé de poser beaucoup plus de questions au métier, au sachant métier, au PO. Et de ce comportement-là va découler un changement de vision de ces mêmes personnes vis-à-vis des développeurs. Le dev, en général, bien souvent, dans beaucoup d'équipes, est considéré comme celui qui parle au code, qui parle à son écran. et qui ne s'intéresse pas au métier, qui ne comprend pas la valeur business. Donc on ne lui demande pas de s'y intéresser. Et je ne pense pas que ce soit une bonne dynamique. A l'inverse, si vous commencez à écrire des tests purement métier, à valider des cas, vous allez devoir poser les questions. Comment on traite cette donnée ? Comment on traite ce cas-là ? Quel est le processus pour passer de tel cas à tel cas ? Et le fait de poser ces questions, vraiment, ça va changer l'approche et le regard que le reste de l'équipe porte sur votre travail. Moi je trouve ça vraiment très très important. Ça change beaucoup de choses. Mais ça n'en change pas que là. Ça en change aussi au niveau du code. Parce que mine de rien, quand on a des tests unitaires automatisables, qui valident vraiment une valeur métier, on peut retransformer l'implémentation. Il n'y a pas de problème. On peut faire du refacto. On peut réécrire des blocs quand c'est difficile à maintenir. Le test unitaire est là pour valider que le fonctionnel, le fonctionnement global, est toujours bon. Un effet de bord de cette approche est qu'aujourd'hui je ne me pose plus la question, par exemple, comment tester mes méthodes privées. Privé au public, mon test s'en fiche et il va valider un comportement, pas une implémentation. De cette manière, mon implémentation elle pourra évoluer, être mise au propre, voire être totalement réécrite si besoin. Je n'aurai pas besoin de reprendre mes tests, ça ne va pas les casser. De ce point de vue, sur mes expériences d'origine, j'avais raison. de ne pas vouloir modifier mon code pour le mettre sous test. Ça aurait été une mauvaise solution à un vrai problème. En revanche, là où j'avais tort, c'est que le code doit être conçu pour pouvoir être testé simplement. Une des meilleures façons de rendre notre code facilement testable, c'est de s'occuper d'abord de l'aspect métier, du code, du traitement métier pur. On va mettre du test là-dessus, on va faire notre implémentation, et ensuite seulement, on travaillera sur toute la... tuyauterie technique, les accès base de données, les accès réseau, toutes ces choses-là. Mais d'abord, la valeur métier, par le test, par le code. Avec tout ce qu'on vient de voir, je pense qu'on peut s'essayer à une nouvelle définition du test unitaire. Aujourd'hui, quand je dis unitaire, personnellement, j'entends la plus petite unité de traitement métier possible. Un test unitaire ne va donc plus couvrir une fonction de méthode, mais un cas métier. Une seule et unique typologie. de données, avec un entrant reproductible et une sortie systématiquement prévisible. Pour résumer, je dirais donc qu'un test unitaire, ça va être un test simple qui ne couvre qu'un seul cas métier. Il doit être rapide d'exécution pour s'intégrer facilement dans un process d'automatisation. Et enfin, comme je l'ai déjà dit plusieurs fois, il ne doit tester qu'un comportement métier, jamais une implémentation. Mon code doit rester libre d'évoluer sans risque de casser la logique métier. Et ça, Seul des tests avec une orientation purement métier pourra vous y amener. Il reste encore la question de comment produire de tels tests, et ce sera pour de prochains épisodes dans lesquels je parlerai tour à tour de TDD, d'inversant de dépendance, de mock, de fake et tout un tas d'autres techniques qui permettent d'arriver là. Voilà ma contribution sur la notion de test unitaire. Comme vous le voyez, c'est pas si simple que ça en a l'air. J'espère que cet épisode vous aura plu, qu'il vous donnera envie de vous y mettre ou d'approfondir vos connaissances sur le testing. Pour vous entraîner, je vous invite vraiment à participer au coding dojo proche de chez vous. On progresse toujours mieux à plusieurs. A bientôt pour un prochain épisode. D'ici là, dites-les bien. Vous délire ?
Description
Notion centrale et a priori de base dans le parcours de dev, discutons un peu des écarts de visions pouvant exister sur les tests unitaires.
Hébergé par Ausha. Visitez ausha.co/politique-de-confidentialite pour plus d'informations.
Transcription
Bonjour à tous et bienvenue sur ce nouvel épisode du podcast PunkinDev. Les tests. Les tests sont un passage incontournable de l'activité de dev. Il faut forcément tester, de quelque manière que ce soit. Certains font des tests automatisés, d'autres font des tests de qualification, ou bien des tests de charge, des tests de non-régression, et bien d'autres typologies de tests encore. Quand on parle de code, on associe souvent au développement la rédaction de tests unitaires associés. Combien de fois m'a-t-on demandé un chiffrage R plus TU, à savoir réalisation plus TU, test unitaire ? Mettons aujourd'hui de côté la pertinence de ce genre de demande. Après la réalisation, il reste tout de même cette notion de test unitaire. C'est quelque chose dont on parle très souvent, sans forcément être très clair sur ce qu'on met dedans. C'est lors d'une discussion à ce sujet, pendant un after du Mug à Lyon, que j'ai pris conscience que ma définition du test unitaire avait grandement évolué au fil des ans. Tentons aujourd'hui de répondre à cette simple question. Mais en fait, c'est quoi un test unitaire ? Prenons d'abord le mot test Qu'est-ce qu'on entend par test Pour donner une définition un petit peu simple, on pourrait dire qu'il s'agit juste d'une procédure visant à valider le bon fonctionnement d'une certaine quantité de code. que le comportement codé correspond bien à celui attendu. Par abus de langage, on pourrait simplement parler de vérification. Mais il y a ensuite la notion d'unitaire. Qu'est-ce qu'on entend par unitaire ? Pour moi ici, l'idée c'est d'avoir un test qu'on peut considérer comme petit et léger, afin qu'il soit automatisable et réexécutable à volonté, sans passer des heures à attendre que la machine termine le travail. En résumé, un test unitaire doit valider le bon fonctionnement du code, mais de manière rapide. Mais alors, pourquoi parle-t-on d'unitaire ? Qu'est-ce que c'est une unité ? Et puis une unité de quoi ? Sur quel périmètre est-ce qu'on choisit de travailler ? Et c'est là que le concept devient un peu plus vaporeux et beaucoup plus sujet à interprétation qu'il n'en a l'air. Pour mes tout premiers tests unitaires, il y a fort longtemps, je considérais que l'unité, c'était la fonction ou la méthode. Une méthode égale un test. Avec mon recul actuel, bien que discutable, je trouve que cette approche a au moins le mérite d'exister. Elle permet, même à un niveau assez faible, de disposer tout de même de tests, et donc d'une base sur laquelle travailler. Je trouve ça plus simple de faire progresser une pratique existante que de devoir initier une pratique à partir de rien. Et au final, je préfère avoir un dev qui débute dans l'écriture de ses tests, plutôt qu'un dev qui prétend pouvoir s'en passer. Là où il y a une démarche d'automatisation, j'estime qu'il y a une démarche d'amélioration, et qu'on peut avancer. Mais on ne va pas se voiler la face. Il va y en avoir du chemin à parcourir, avant que ces petits tests-là ne jouent pleinement leur rôle. C'est donc avec cette approche quelque peu naïve, que j'ai commencé à écrire mes premiers tests unitaires, et que j'ai rapidement rencontré des problèmes. parfois tout simple, mais qui me bloquait totalement à cette époque. Le premier, pour ne citer que lui, particulièrement symptomatique. Comment faire pour tester mes méthodes privées ? Ces méthodes contenant des algos importants, je voulais absolument les mettre sous test, mais en même temps, les méthodes en question n'étaient pas accessibles dans mon projet de test, et je trouvais assez discutable de devoir modifier mon code de prod simplement pour pouvoir le mettre sous test. Je vais me permettre une petite pause et un petit focus sur cette réflexion. Le fait de devoir modifier le code pour pouvoir le mettre sous test. J'imaginais pas du tout à ce moment là les implications potentielles d'une telle question. On touche ici une notion fondamentale sur laquelle je vais revenir assez vite. Si je reviens à ma petite histoire donc, après ces quelques difficultés, et faute d'encadrement de coaching efficace, j'étais bloqué. Et j'ai été un peu contraint, contre mon gré. de mettre de côté mes envies de tests unitaires. Franchir tout seul cette marche était trop difficile. J'aurais eu un lead dev, un coach, un formateur, juste un dev expérimenté qui m'aurait montré le chemin, qui m'aurait donné les bons sites, les bons bouquins à lire. J'aurais peut-être pu m'en sortir, mais là j'étais vraiment seul. Le temps passant, j'ai longuement erré, et j'ai fini par expérimenter des choses. bien souvent en coding dojo ou sur des projets simples. Les projets Legacy font encore aujourd'hui figure de cas particuliers, tant ils peuvent parfois représenter un défi colossal quand on veut leur greffer des tests unitaires. Au final, c'est surtout donc sur de nouveaux projets, et avec le bon entourage, que j'ai pu avoir l'évolution la plus intéressante. J'ai pu faire évoluer ma vision du test unitaire avec une relation 1-1 avec l'implémentation, cette vision d'une méthode, un test. Et petit à petit, j'ai commencé à écrire des tests qui étaient moins en relation avec le code, et plus en relation avec des comportements métiers. À essayer à chaque fois, plutôt que de tester mon implémentation, tester un comportement métier. Ça peut avoir l'air de rien, dit comme ça, mais cette posture change absolument tout. On ne va plus essayer de valider le code, comme je le donnais dans ma définition au départ. On va valider un comportement métier, une valeur business. Le fait de se mettre... dans cette optique, de valider du métier avant de valider du code, ça va avoir un impact profond. On va être obligé de poser beaucoup plus de questions au métier, au sachant métier, au PO. Et de ce comportement-là va découler un changement de vision de ces mêmes personnes vis-à-vis des développeurs. Le dev, en général, bien souvent, dans beaucoup d'équipes, est considéré comme celui qui parle au code, qui parle à son écran. et qui ne s'intéresse pas au métier, qui ne comprend pas la valeur business. Donc on ne lui demande pas de s'y intéresser. Et je ne pense pas que ce soit une bonne dynamique. A l'inverse, si vous commencez à écrire des tests purement métier, à valider des cas, vous allez devoir poser les questions. Comment on traite cette donnée ? Comment on traite ce cas-là ? Quel est le processus pour passer de tel cas à tel cas ? Et le fait de poser ces questions, vraiment, ça va changer l'approche et le regard que le reste de l'équipe porte sur votre travail. Moi je trouve ça vraiment très très important. Ça change beaucoup de choses. Mais ça n'en change pas que là. Ça en change aussi au niveau du code. Parce que mine de rien, quand on a des tests unitaires automatisables, qui valident vraiment une valeur métier, on peut retransformer l'implémentation. Il n'y a pas de problème. On peut faire du refacto. On peut réécrire des blocs quand c'est difficile à maintenir. Le test unitaire est là pour valider que le fonctionnel, le fonctionnement global, est toujours bon. Un effet de bord de cette approche est qu'aujourd'hui je ne me pose plus la question, par exemple, comment tester mes méthodes privées. Privé au public, mon test s'en fiche et il va valider un comportement, pas une implémentation. De cette manière, mon implémentation elle pourra évoluer, être mise au propre, voire être totalement réécrite si besoin. Je n'aurai pas besoin de reprendre mes tests, ça ne va pas les casser. De ce point de vue, sur mes expériences d'origine, j'avais raison. de ne pas vouloir modifier mon code pour le mettre sous test. Ça aurait été une mauvaise solution à un vrai problème. En revanche, là où j'avais tort, c'est que le code doit être conçu pour pouvoir être testé simplement. Une des meilleures façons de rendre notre code facilement testable, c'est de s'occuper d'abord de l'aspect métier, du code, du traitement métier pur. On va mettre du test là-dessus, on va faire notre implémentation, et ensuite seulement, on travaillera sur toute la... tuyauterie technique, les accès base de données, les accès réseau, toutes ces choses-là. Mais d'abord, la valeur métier, par le test, par le code. Avec tout ce qu'on vient de voir, je pense qu'on peut s'essayer à une nouvelle définition du test unitaire. Aujourd'hui, quand je dis unitaire, personnellement, j'entends la plus petite unité de traitement métier possible. Un test unitaire ne va donc plus couvrir une fonction de méthode, mais un cas métier. Une seule et unique typologie. de données, avec un entrant reproductible et une sortie systématiquement prévisible. Pour résumer, je dirais donc qu'un test unitaire, ça va être un test simple qui ne couvre qu'un seul cas métier. Il doit être rapide d'exécution pour s'intégrer facilement dans un process d'automatisation. Et enfin, comme je l'ai déjà dit plusieurs fois, il ne doit tester qu'un comportement métier, jamais une implémentation. Mon code doit rester libre d'évoluer sans risque de casser la logique métier. Et ça, Seul des tests avec une orientation purement métier pourra vous y amener. Il reste encore la question de comment produire de tels tests, et ce sera pour de prochains épisodes dans lesquels je parlerai tour à tour de TDD, d'inversant de dépendance, de mock, de fake et tout un tas d'autres techniques qui permettent d'arriver là. Voilà ma contribution sur la notion de test unitaire. Comme vous le voyez, c'est pas si simple que ça en a l'air. J'espère que cet épisode vous aura plu, qu'il vous donnera envie de vous y mettre ou d'approfondir vos connaissances sur le testing. Pour vous entraîner, je vous invite vraiment à participer au coding dojo proche de chez vous. On progresse toujours mieux à plusieurs. A bientôt pour un prochain épisode. D'ici là, dites-les bien. Vous délire ?
Share
Embed
You may also like