« LeSS - Tests unitaires » : différence entre les versions

De Wiki Agile
m Ajout encadré
 
(14 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 6 : Ligne 6 :
----
----
Traducteur : Nicolas Mereaux<br />
Traducteur : Nicolas Mereaux<br />
Relecteur : Fabrice Aimetti<br />
Date : 29/06/2022<br />
Date : 29/06/2022<br />
----
----
Ligne 87 : Ligne 88 :
Ce n’est pas toujours le cas. Si le code n’a pas une bonne testabilité, vous pourriez tout de même être capable techniquement d’écrire le test unitaire qui va avec. Mais un test unitaire qui a été écrit pour un code non-testable est généralement très difficile à maintenir et à comprendre. Par conséquent, il n’y a pas vraiment de raison d’en avoir un.
Ce n’est pas toujours le cas. Si le code n’a pas une bonne testabilité, vous pourriez tout de même être capable techniquement d’écrire le test unitaire qui va avec. Mais un test unitaire qui a été écrit pour un code non-testable est généralement très difficile à maintenir et à comprendre. Par conséquent, il n’y a pas vraiment de raison d’en avoir un.


'''Le secret du test unitaire n’est pas d’écrire du test, mais d’écrire du code testable sous test.''' Nous voulons du code testable et facile à tester, ce qui s’avère une démarche gagnant-gagnant. Nous ne voulons pas de code non-testable et difficile à maintenir, ce qui serait une démarche perdant-perdant.
'''Le secret du test unitaire n’est pas d’écrire du test, mais d’écrire un code testable sous test.''' Nous voulons du code testable et facile à tester, ce qui s’avère une démarche gagnant-gagnant. Nous ne voulons pas de code non-testable et difficile à maintenir, ce qui serait une démarche perdant-perdant.


=== Je peux ajouter les tests unitaires plus tard ===
=== Je peux ajouter les tests unitaires plus tard ===
Well, try asking the rock climbers to set their anchors later.


Eh bien, essayez donc de demander à des grimpeurs de mettre leurs pitons plus tard.
Eh bien, essayez donc de demander à des grimpeurs de mettre leurs pitons plus tard.


[[Image:Xunit_test_fr.png|Xunit_test_fr.png|border|link=|500px]]
[[Image:Xunit_test_fr.png|Xunit_test_fr.png|border|link=|500px]]
== Good Unit Test Patterns ==


== Schéma pour de bons tests unitaires ==
== Schéma pour de bons tests unitaires ==
=== No news is good news ===


=== Pas de nouvelles, bonnes nouvelles ===
=== Pas de nouvelles, bonnes nouvelles ===


If the test passes, it should just print OK (and perhaps some dots to show the progress). No other information.
Si le test passe, il devrait afficher seulement OK (voire quelques points pour afficher son avancement). Aucune autre information n'est nécessaire.
 
Si le test passe, il devrait afficher seulement OK (voire quelques points pour afficher son avancement). Aucune autre information nécessaire.


[[Image:unit_test_success.png|unit_test_success.png|border|link=|800px]]
[[Image:unit_test_success.png|unit_test_success.png|border|link=|800px]]


Rule of thumb:
Règle empirique :


En règle générale :
Aucune intervention humaine ne devrait être nécessaire pour préparer l’exécution du test, exécuter les cas de tests ou en vérifier les résultats.


<blockquote>No human intervention should be needed to get ready for the test, running the test cases or checking the result.
Et lorsqu’un test unitaire échoue, il devrait nous fournir toutes les informations nécessaires. L’objectif est de limiter la durée pendant laquelle vous êtes occupé à débogguer le code concerné.
</blockquote>
<blockquote>Aucune intervention humaine ne devrait être nécessaire pour préparer l’exécution du test, exécuter les cas de tests ou en vérifier les résultats.
</blockquote>
And when it fails, it should provide precise information. The goal is to limit the amount of time you spend on debugging when the test fails.<br />


[[Image:342xNxunit_test_fail.png|342xNxunit_test_fail.png|border|link=]]
[[Image:342xNxunit_test_fail.png|342xNxunit_test_fail.png|border|link=]]
Et lorsqu’un test unitaire échoue, il devrait nous fournir toutes les informations nécessaires. L’objectif est de limiter la durée pendant laquelle vous êtes occupés à débogguer le code concerné.


=== Arranger, Agir, Auditer (''Arrange'', ''Act'', ''Assert'') ===
=== Arranger, Agir, Auditer (''Arrange'', ''Act'', ''Assert'') ===


A good pattern to follow in a unit test is “'''AAA'''”: '''Arrange''', '''Act''' and '''Assert'''.
Un bon schéma à suivre en ce qui concerne les tests unitaires est "'''AAA'''" : '''Arrange (dans le sens de mettre en place)''', '''Act (dans le sens d’une action faite sur quelque chose)''' et '''Assert (dans le sens de contrôler)'''.
 
Un bon schéma à suivre en ce qui concerne les tests unitaires est '''AAA''': '''Arrange (dans le sens de mettre en place)''', '''Act (dans le sens d’une action faite sur quelque chose)''' et '''Assert (dans le sens de contrôler)'''
 
If you can easily find this pattern in each of your test cases, your tests should be easy to understand, and they should be fairly specific and to the point. One unit test case should test only one thing. Therefore, there should be only one set of AAA in one test case. A test case shouldn’t be very long (longer than 10 lines of code) if it follows the AAA pattern.


Si vous pouvez repérer ce schéma dans chacun de vos cas de tests, vos tests devraient facile à comprendre, et ils devraient s’avérer suffisamment spécifiques et aller droit au but. Un cas de test unitaire devrait tester une seule et unique chose. Par conséquent, il devrait y avoir un seul AAA dans un cas de test. Un cas de test ne devrait pas être très prolixe (c’est-à-dire plus de 10 lignes de code) s’il suit le schéma AAA.
Si vous pouvez repérer ce schéma dans chacun de vos cas de tests, vos tests devraient être facile à comprendre, et ils devraient s’avérer suffisamment spécifiques et aller droit au but. Un cas de test unitaire devrait tester une seule et unique chose. Par conséquent, il devrait y avoir un seul AAA dans un cas de test. Un cas de test ne devrait pas être très prolixe (c’est-à-dire plus de 10 lignes de code) s’il suit le schéma AAA.


<pre>import unittest class TestGroupForTextWrapping(unittest.TestCase):
<pre>import unittest class TestGroupForTextWrapping(unittest.TestCase):
Ligne 149 : Ligne 132 :
=== Développement piloté par le comportement (BDD) ===
=== Développement piloté par le comportement (BDD) ===


Similar to the '''AAA''' pattern, the '''BDD''' style uses three other keywords to specify each test case: '''Given''', '''When''' and '''Then'''. (You can also use '''And''' as another keyword.)
Identique au schéma '''AAA''', le '''BDD''' utilise trois mots-clés différents pour spécifier chaque cas de test : '''Étant donné''', '''Lorsque''' et '''Alors'''. (Vous pouvez aussi utiliser '''Et''' comme mot-clé supplémentaire)
 
Identique au schéma '''AAA''', le BDD utilise trois mots-clés différents pour spécifier chaque cas de test : '''Étant donné''', '''Lorsque''' et '''Alors'''. (Vous pouvez aussi utiliser '''Et''' comme mot-clé supplémentaire)
 
<pre>Given The Text Wrapper's Width Defined As 10
And Using '-' As Word Connector
When The Wrapper Wrap Text Length is Less Than 10
Then The Text Should Not Be Wrapped


<pre>
Given / Étant donné que la longueur du texte pour le retour à la ligne est défini à 10
Given / Étant donné que la longueur du texte pour le retour à la ligne est défini à 10
And / Et que le caractère '-' est utilisé comme connecteur entre deux mots
And / Et que le caractère '-' est utilisé comme connecteur entre deux mots
When / Lorsque la longueur du texte est inférieure à 10
When / Lorsque la longueur du texte est inférieure à 10
Then / Alors le texte ne devrait pas être retourné à la ligne</pre>
Then / Alors le texte ne devrait pas être retourné à la ligne</pre>
As you can see, “given-when-then” maps to “arrange-act-assert” pretty well. They both simply define a state transition of a Finite State Machine (FSM). You can find more on this in the [https://sites.google.com/site/unclebobconsultingllc/the-truth-about-bdd Uncle Bob’s article]. Some differences:
Comme vous pouvez le constater, le triptyque « étant donné - lorsque - alors » correspond plutôt bien avec le triptyque « Arrange - Act - Assert ». Ils définissent tous les deux un état transition d’une machine à état finie. Vous pouvez en savoir plus en consultant cet article d’[https://sites.google.com/site/unclebobconsultingllc/the-truth-about-bdd Oncle Bob]. Voici quelques différences entre les deux :


* BDD is more “outside-in”, which means that it emphasises more the external behaviour
Comme vous pouvez le constater, le triptyque "étant donné - lorsque - alors" s'allie plutôt bien avec le triptyque "Arrange - Act - Assert". Ils définissent tous les deux un état transition d’une machine à état finie. Vous pouvez en savoir plus en consultant cet article d’[https://sites.google.com/site/unclebobconsultingllc/the-truth-about-bdd Oncle Bob]. Voici quelques différences entre les deux :
* With BDD, you need to define a '''domain specific language''' to write your test specifications. Because of this, usually you’ll need a different framework. One example for Python is [http://pythonhosted.org/behave/ behave].
* Le BDD est davantage orienté "dehors vers dedans", cela veut dire qu’il met davantage l’accent sur le comportement externe
* Le BDD est davantage « dehors-dedans », cela veut dire qu’il met davantage l’accent sur le comportement externe
* Avec le BDD, vous devez définir un '''langage spécifique au domaine''' pour écrire vos spécifications de tests. À cause de cela, vous aurez besoin généralement d’un ''framework'' supplémentaire. Par exemple, pour Python vous pourrez utilisez [https://pypi.org/project/behave/ behave].
* Avec le BDD, vous devez définir un '''langage spécifique au domaine''' pour écrire vos spécifications de tests. À cause de cela, vous aurez besoin généralement d’un ''framework'' supplémentaire. Par exemple, pour Python vous pourrez utilisez [http://pythonhosted.org/behave/ behave].


=== La règle d’or du test unitaire ===
=== La règle d’or du test unitaire ===
In general, a good rule for unit test case is:


De manière générale, une bonne règle d’or pour des tests unitaires serait :
De manière générale, une bonne règle d’or pour des tests unitaires serait :


<blockquote>'''Each unit test case should be very limited in scope.'''
'''Chaque cas de test unitaire devrait comporter un périmètre très restreint.'''
</blockquote>
<blockquote>'''Chaque cas de test unitaire devrait comporter un périmètre très restreint.'''
</blockquote>
So that:


De telle manière que :
De telle manière que... :


* When the test fails, no debugging is needed to locate the problem.
* Tests are stable because dependencies are simple.
* Less duplication, easier to maintain.
* Lorsque le test échoue, qu’il ne soit pas nécessaire de faire du déboggage pour localiser le problème.
* Lorsque le test échoue, qu’il ne soit pas nécessaire de faire du déboggage pour localiser le problème.
* Les tests soient stables car les dépendances sont limitées.
* Les tests soient stables car les dépendances sont limitées.
* Il y ait moins de duplications, que ce soit plus facile à maintenir
* Il y ait moins de duplications, que ce soit plus facile à maintenir.
 
There is no secret to write good unit test. In order to write good unit test, you need to create easy-to-test design.


Il n’existe pas de secrets pour écrire un bon test unitaire. Afin d’écrire un bon test unitaire, vous devez créer une conception qui soit facile à tester.
Il n’existe pas de secrets pour écrire un bon test unitaire. Afin d’écrire un bon test unitaire, vous devez créer une conception qui soit facile à tester.