Table des matières:
Vidéo: Tests unitaires et TDD en Java avec JUnit 2024
JUnit est un framework standardisé pour tester des unités Java (c'est-à-dire des classes Java). JUnit peut être automatisé pour retirer une partie du travail des tests.
Imaginez que vous ayez créé un type enum avec trois valeurs: VERT, JAUNE et ROUGE. Le listing 1 contient le code:
Listing 1
public Enum SignalColor {VERT, JAUNE, ROUGE}
Un feu de circulation a un état (qui est un nom de fantaisie pour la couleur du feu).
classe publique TrafficLight {SignalColor state = SignalColor. ROUGE;
Si vous connaissez l'état actuel du feu, vous pouvez décider du prochain état du feu.
public void nextState () {commutateur (état) {case ROUGE: état = SignalColor. VERT; Pause; case YELLOW: état = SignalColor. ROUGE; Pause; case GREEN: state = SignalColor. JAUNE; Pause; par défaut: state = SignalColor. ROUGE; break}}}
Vous pouvez également changer l'état du feu un certain nombre de fois:
public void change (int nombreDeHeures) {for (int i = 0; iEn un mot, vous avez la classe TrafficLight dans la liste 2.
Liste 2
public class TrafficLight {SignalColor state = SignalColor. ROUGE; public void nextState () {switch (état) {case ROUGE: état = SignalColor. VERT; Pause; case YELLOW: état = SignalColor. ROUGE; Pause; case GREEN: state = SignalColor. JAUNE; Pause; par défaut: state = SignalColor. ROUGE; }} public void changement (int numberOfTimes) {pour (int i = 0; iDans les temps anciens, vous pourriez avoir continué à écrire du code, créant plus de classes, en appelant nextState et en changeant les méthodes dans la liste 2. Ensuite, après plusieurs mois de codage, vous pouvez faire une pause pour tester votre travail.
Et quelle surprise! Vos tests échoueraient misérablement! Vous ne devriez jamais retarder les tests pendant plus d'un jour ou deux. Testez tôt et testez souvent!
Une philosophie sur les tests dit que vous devriez tester chaque morceau de code dès que vous l'avez écrit. Bien sûr, l'expression "morceau de code" ne semble pas très scientifique. Il ne serait pas utile que les développeurs se promènent en parlant des «tests de code de morceau» qu'ils ont fait cet après-midi. Il est préférable d'appeler chaque segment de code unité , et d'amener les développeurs à parler de tests unitaires .
L'unité la plus commune pour tester est une classe. Ainsi, un développeur Java typique teste chaque classe dès que le code de la classe est écrit.
Alors, comment allez-vous tester un cours? Un novice pourrait tester la classe TrafficLight en écrivant une classe supplémentaire - une classe contenant une méthode principale. La méthode principale crée une instance de TrafficLight, appelle nextState et change methods, et affiche les résultats.Le novice examine les résultats et les compare avec certaines valeurs attendues.
Après avoir écrit des méthodes principales pour des dizaines, des centaines ou même des milliers de classes, le novice (maintenant un développeur à part entière) en a assez de la routine de test et cherche des moyens d'automatiser la procédure de test. Fatigué ou pas, un développeur pourrait essayer de déchiffrer les tests codés à la main d'un autre développeur. Sans avoir de normes ou de lignes directrices pour la construction de tests, lire et comprendre les tests d'un autre développeur peut être difficile et fastidieux.
Alors JUnit vient à la rescousse!.
Pour savoir comment Eclipse automatise l'utilisation de JUnit, procédez comme suit:
Créez un projet Eclipse contenant les listes 1 et 2.
Dans Windows, cliquez avec le bouton droit sur TrafficLight de l'Explorateur de packages. branche java. Sur un Mac, cliquez tout en maintenant la touche Contrôle enfoncée sur TrafficLight de l'Explorateur de packages. branche java.
Un menu contextuel apparaît.
Dans le menu contextuel, sélectionnez Nouveau → JUnit Test Case.
Par conséquent, la boîte de dialogue Nouveau cas de test JUnit apparaît.
Cliquez sur Suivant en bas de la boîte de dialogue Nouveau cas de test JUnit.
Par conséquent, vous voyez la deuxième page de la boîte de dialogue Nouveau cas de test JUnit. La deuxième page répertorie les méthodes appartenant (directement ou indirectement) à la classe TrafficLight.
Cochez la case intitulée Feu de circulation.
Par conséquent, Eclipse place des coches dans les cases nextState () et change (int) .
Cliquez sur Terminer en bas de la boîte de dialogue Nouveau cas de test JUnit.
JUnit ne fait pas officiellement partie de Java. Au lieu de cela vient avec son propre ensemble de classes et de méthodes pour vous aider à créer des tests pour votre code. Après avoir cliqué sur Terminer, Eclipse vous demande si vous souhaitez inclure les classes et les méthodes JUnit dans votre projet.
Sélectionnez Effectuer l'action suivante et ajouter la bibliothèque JUnit 4 au chemin de construction. Puis cliquez sur OK.
Eclipse ferme les boîtes de dialogue et votre projet a un tout nouveau TrafficLightTest. fichier java. Le code du fichier est indiqué dans l'extrait 3.
Le code de l'extrait 3 contient deux tests, et les deux tests contiennent des appels à une méthode d'échec de sondage désagréable. Eclipse vous demande d'ajouter du code pour faire passer ces tests.
Supprime les appels à la méthode d'échec. Au lieu des appels de la méthode fail, tapez le code affiché en gras dans le Listing 4.
Dans l'Explorateur de packages, cliquez avec le bouton droit (sous Windows) ou cliquez en maintenant la touche Ctrl enfoncée (sur un Mac) sur le TrafficLightTest. branche java. Dans le menu contextuel résultant, sélectionnez Exécuter en tant que → JUnit Test.
Eclipse pourrait avoir plus d'un type de framework de test JUnit dans sa manche. Si c'est le cas, vous pouvez voir une boîte de dialogue comme celle ci-dessous. Si vous le faites, sélectionnez Eclipse JUnit Launcher, puis cliquez sur OK.
Par conséquent, Eclipse exécute votre TrafficLightTest. programme Java. Eclipse affiche le résultat de l'exécution devant son propre Explorateur de packages. Le résultat ne montre aucune erreur et aucun échec. Ouf!
Annonce 3
importer static org. junit. Affirmer. *; import org. junit. Tester; public class TrafficLightTest {@Test public void testNextState () {fail ("Pas encore implémenté");} @Test public void testChange () {fail ("Pas encore implémenté");}}Listing 4
import org statiquejunit. Affirmer. *; import org. junit. Tester; Classe publique TrafficLightTest {@Test public void testNextState () { Lumière TrafficLight = new TrafficLight (); assertEquals (SignalColor RED, état de la lumière); lumière. nextState (); assertEquals (SignalColor, VERT, état lumineux); lumière. nextState (); assertEquals (SignalColor.JAUNE, état de la lumière); lumière. nextState (); assertEquals (SignalColor RED, état de la lumière); } @Test public void testChange () { Lumière TrafficLight = new TrafficLight (); lumière. changer (5); assertEquals (SignalColor.JAUNE, état de la lumière); }}Lorsque vous sélectionnez Exécuter en tant que → JUnit Test, Eclipse ne recherche pas de méthode principale. Au lieu de cela, Eclipse recherche des méthodes commençant par @Test et d'autres choses de ce genre. Eclipse exécute chacune des méthodes @Test.
Des choses comme @Test sont des annotations Java .
Le Listing 4 contient deux méthodes @Test: testNextState et testChange. La méthode testNextState met la méthode TrafficLight nextState à l'essai. De même, la méthode testChange fait fléchir les muscles de la méthode de changement TrafficLight.
Considérez le code dans la méthode testNextState. La méthode testNextState appelle de manière répétée la méthode nextState de la classe TrafficLight et la méthode assertEquals de JUnit. La méthode assertEquals prend deux paramètres: une valeur attendue et une valeur réelle.
Dans l'appel assertEquals le plus haut, la valeur attendue est SignalColor. ROUGE. Vous vous attendez à ce que le feu de circulation soit ROUGE parce que, dans la liste 2, vous initialisez l'état de la lumière avec la valeur SignalColor. ROUGE.
Dans l'appel assertEquals le plus haut, la valeur réelle est light. state (la couleur qui est réellement stockée dans la variable d'état du feu).
Si la valeur réelle est égale à la valeur attendue, l'appel à assertEquals passe et JUnit continue d'exécuter les instructions de la méthode testNextState.
Mais si la valeur réelle est différente de la valeur attendue, assertEquals échoue et le résultat de l'exécution affiche l'échec. Par exemple, considérez ce qui se passe lorsque vous modifiez la valeur attendue dans le premier appel assertEquals dans l'extrait 4:
@Test public void testNextState () {TrafficLight light = new TrafficLight (); assertEquals (SignalColor.JAUNE, état de la lumière);Immédiatement après sa construction, la couleur d'un feu de circulation est ROUGE et non JAUNE. Ainsi, la méthode testNextState contient une fausse assertion et le résultat de Run As → JUnit ressemble à la mauvaise fiche d'un enfant.
Avoir testéNextState avant testChange dans Listing 4 ne garantit pas que JUnit va exécuter testNextState avant d'exécuter testChange. Si vous avez trois méthodes @Test, JUnit peut les exécuter du plus haut au plus bas, du plus bas au plus haut, de la méthode du milieu au plus haut au plus bas, ou dans n'importe quel ordre. JUnit peut même faire une pause au milieu d'un test pour exécuter des parties d'un autre test. C'est pourquoi vous ne devriez jamais faire d'hypothèses sur le résultat d'un test lorsque vous écrivez un autre test.
Vous pourriez vouloir que certaines instructions soient exécutées avant que l'un des tests ne commence.Si vous le faites, placez ces instructions dans une méthode nommée setUp, et préférez cette méthode avec une annotation @Before. (Voir la case setUp () dans la figure de l'étape 3 du Listing 2, ci-dessus.)
Voici les nouvelles: Toutes les méthodes assertEquals ne sont pas égales! Imaginez l'ajout d'une classe Driver au code de votre projet. "Classe de pilote" ne signifie pas un pilote d'imprimante ou un pilote de pile. Cela signifie qu'une personne conduit une voiture - une voiture qui s'approche de votre feu de circulation. Pour les détails, voir Listing 5.
Listing 5
public class Driver {public double vitesse (TrafficLight light) {switch (état de la lumière) {case RED: return 0. 0; case JAUNE: renvoie 10. 0; cas VERT: retour 30. 0; par défaut: return 0. 0;}}}Lorsque la lumière est rouge, la vitesse du conducteur est 0. 0. Lorsque la lumière est jaune, la voiture ralentit jusqu'à un coffre-fort 10. 0. Lorsque la lumière est verte, la voiture croise à une vitesse de 30. 0.
(Dans cet exemple, les unités de vitesse n'ont pas d'importance, elles peuvent être des miles par heure, des kilomètres par heure, etc.). voiture est à Boston ou à New York, dans ce cas, la vitesse pour JAUNE devrait être beaucoup plus élevée que la vitesse pour VERT, et la vitesse pour ROUGE ne devrait pas être 0. 0.)
Pour créer des tests JUnit pour le La classe de pilote, suivez les étapes 1 à 9 répertoriées précédemment dans cet article, mais veillez à apporter les modifications suivantes:
À l'étape 2, cliquez avec le bouton droit ou cliquez sur le pilote. branche java au lieu de TrafficLight. branche java.
À l'étape 5, cochez la case Pilote.
À l'étape 8, supprimez les appels de la méthode fail pour créer la classe DriverTest indiquée dans le Listing 6. (Le code que vous tapez est en gras.)
Listing 6
import static org. junit. Affirmer. *; import org. junit. Tester; public class DriverTest {@Test public void testVelocity () { Lumière TrafficLight = new TrafficLight (); lumière. changement (7); Pilote de pilote = nouveau pilote (); assertEquals (30,0, pilote, vitesse (lumière), 0, 1); }}Si tout se passe bien, le test JUnit passe avec brio. (Pour être plus précis, le JUnit passe avec la couleur verte!) Donc le fonctionnement de DriverTest n'est ni nouveau ni excitant. Ce qui est excitant, c'est l'appel à assertEquals dans la liste 6.
Lorsque vous comparez deux valeurs doubles dans un programme Java, vous n'avez pas le droit de vous attendre à une égalité sur le nez. Autrement dit, l'une des valeurs doubles peut être 30. 000000000 tandis que l'autre valeur double est plus proche de 30. 000000001. Un ordinateur n'a que 64 bits pour stocker chaque valeur double, et les inexactitudes se glissent ici et là. Donc, dans JUnit, la méthode assertEquals pour comparer les valeurs doubles a un troisième paramètre. Le troisième paramètre représente la marge de manœuvre.
Dans l'extrait 6, l'instruction
assertEquals (30.0, driver.vitocity (light), 0. 1);indique ce qui suit: "Affirmez que la valeur réelle du conducteur. la vitesse (lumière) est à l'intérieur de 0. 1 de la valeur attendue 30. 0. Si oui, l'assertion passe. Sinon, l'assertion échoue. "
Lorsque vous appelez assertEquals pour des valeurs doubles, il peut être difficile de sélectionner une bonne marge d'erreur.Ces chiffres illustrent le genre de choses qui peuvent mal tourner.
Ici, votre marge d'erreur est trop petite.
Là, votre marge d'erreur est trop grande.
Heureusement, dans cet exemple DriverTest, la marge 0. 1 est un pari très sûr. Voici pourquoi:
Lorsque le test assertEquals échoue, il échoue de beaucoup plus de 0. 1.
L'échec signifie avoir un pilote. valeur de vélocité (légère) telle que 0. 0 ou 10. 0.
Dans cet exemple, lorsque le test assertEquals réussit, il représente probablement une égalité complète sur le nez.
La valeur du pilote. la vitesse (lumière) provient directement du code de retour 30. 0 dans le Listing 5. Aucune arithmétique n'est impliquée. Donc, la valeur du pilote. la vitesse (lumière) et la valeur attendue de 30. 0 devrait être exactement la même (ou presque exactement la même chose).