Contenu du cours
Bibliothèque Java JUnit. Types de Tests
Bibliothèque Java JUnit. Types de Tests
Tests Unitaires
Examinons de plus près le concept de test unitaire et pourquoi il est nécessaire.
Notions de base de JUnit
JUnit est un framework pour les tests unitaires qui fournit des annotations pour définir des méthodes de test et des assertions pour vérifier les résultats attendus.
Vous avez déjà rencontré des annotations lors de la surcharge de différentes méthodes. En termes simples, les annotations indiquent au compilateur ou au framework quoi faire avec un module particulier. Elles fournissent également des informations au programmeur sur la signification d'une ligne ou d'un module spécifique dans le programme. Les annotations simplifient grandement la vie et sont utilisées dans presque tous les frameworks. Voyons un exemple simple de test unitaire, et vous comprendrez comment les annotations sont utilisées :
Dans cet exemple :
- L'annotation
@Test
indique que la méthodetestAddition()
est une méthode de test ; Calculator
est la classe que nous testons ;Assertions.assertEquals(8, result)
vérifie que le résultat de l'addition est égal à 8.
Par conséquent, nous avons vérifié que la méthode add()
effectue correctement sa fonction. Cependant, un seul test unitaire n'est pas suffisant, car il pourrait y avoir de nombreux autres problèmes. Par exemple, un utilisateur pourrait passer null
au lieu d'un nombre, ou les nombres pourraient dépasser la plage acceptable. Ces cas devraient également être couverts par des tests unitaires.
Remarque
Nous allons approfondir l'écriture et l'apprentissage des tests unitaires dans la prochaine section. Ce chapitre est conçu à des fins d'information et pour vous aider à comprendre pourquoi il est nécessaire d'écrire des tests unitaires.
Que doivent vérifier les tests unitaires ?
Imaginons que nous devons tester une méthode simple. À cette fin, nous allons écrire une méthode qui prend une chaîne sous la forme de "Name||Address||email||phoneNumber||"
et la divise en une map avec les clés et valeurs correspondantes.
Le code de cette méthode ressemblera à ceci :
Main
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static Map<String, String> convertToMap(String input) { Map<String, String> resultMap = new HashMap<>(); String[] parts = input.split("\\|\\|"); resultMap.put("Name", parts[0]); resultMap.put("Address", parts[1]); resultMap.put("Email", parts[2]); resultMap.put("PhoneNumber", parts[3]); return resultMap; } public static void main(String[] args) { String input = "John Doe||123 Maple Street||johndoe@example.com||555-1234"; Map<String, String> result = convertToMap(input); System.out.println(result); } }
Remarque
Pour diviser ce format, nous devons diviser par le symbole
||
, mais nous devons indiquer au compilateur qu'il s'agit bien d'un symbole et non d'une commande. Par conséquent, nous utilisons\\
avant le symbole. Ainsi, notre regex ressemble à ceci :\\|\\|
.
La méthode est assez simple à écrire. Mais revenons maintenant à quels cas de test existent pour cette méthode :
- Test de Données Correctes
Test avec une chaîne d'entrée correctement formatée. On s'attend à ce que la méthode retourne une
Map
avec les valeurs correctes pour chaque clé ; - Test de Format Incorrect
Test avec une chaîne qui ne correspond pas au format attendu (par exemple, manquant certains des séparateurs
||
requis ou les ayant en excès) ; - Test de Chaîne Vide
Vérification du comportement de la méthode lorsque la chaîne d'entrée est vide. La méthode devrait soit retourner une
Map
vide, soit lancer une exception ; - Test de Chaîne Nulle
Test du comportement de la méthode lorsque
null
est passé comme chaîne d'entrée.
Allons-y étape par étape. Dans le premier cas de test, nous allons tester le fonctionnement de cette méthode avec des données correctes. Dans la méthode main
, nous avons déjà fait cela lorsque nous avons passé une valeur et reçu les données correctes.
Dans le deuxième cas de test, nous devons passer un format incorrect pour voir comment la méthode se comportera. Par exemple, passons des données séparées par un seul caractère |
:
main
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static Map<String, String> convertToMap(String input) { Map<String, String> resultMap = new HashMap<>(); String[] parts = input.split("\\|\\|"); resultMap.put("Name", parts[0]); resultMap.put("Address", parts[1]); resultMap.put("Email", parts[2]); resultMap.put("PhoneNumber", parts[3]); return resultMap; } public static void main(String[] args) { String input = "John Doe|123 Maple Street|johndoe@example.com|555-1234"; Map<String, String> result = convertToMap(input); System.out.println(result); } }
Comme vous pouvez le voir, nous lançons une IndexOutOfBoundsException
. Cela signifie que le tableau que nous créons à partir de la chaîne d'origine n'a pas 4 éléments comme il devrait en avoir. Le test nous a montré que notre méthode n'est pas parfaite, alors ajoutons une gestion des exceptions en utilisant une simple instruction if :
Ici, nous avons ajouté une vérification de base qui, en cas de données incorrectes, retournera une carte vide et imprimera un message sur le fonctionnement incorrect de la méthode.
Regardons un exemple exécutable :
main
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static Map<String, String> convertToMap(String input) { Map<String, String> resultMap = new HashMap<>(); String[] parts = input.split("\\|\\|"); if (parts.length != 4) { System.out.println("Input string format is not correct"); return new HashMap<>(); } resultMap.put("Name", parts[0]); resultMap.put("Address", parts[1]); resultMap.put("Email", parts[2]); resultMap.put("PhoneNumber", parts[3]); return resultMap; } public static void main(String[] args) { String input = "John Doe|123 Maple Street|johndoe@example.com|555-1234"; Map<String, String> result = convertToMap(input); System.out.println(result); } }
Comme vous pouvez le voir, le troisième cas de test est également couvert par cette vérification ; Si une chaîne vide est passée, elle ne passera pas la validation que nous avons écrite.
Passons au cas où une valeur null
est passée. Nous ne vérifions pas actuellement la chaîne pour null, nous devons donc ajouter cette vérification dans la méthode :
Nous avons ajouté une vérification de null
, et maintenant la méthode retournera une carte vide si null
lui est passé.
Exécutons ce code et voyons le résultat :
main
package com.example; import java.util.HashMap; import java.util.Map; public class Main { public static Map<String, String> convertToMap(String input) { if (input == null) { System.out.println("Input string can't be null!"); return new HashMap<>(); } Map<String, String> resultMap = new HashMap<>(); String[] parts = input.split("\\|\\|"); if (parts.length != 4) { System.out.println("Input string format is not correct"); return new HashMap<>(); } resultMap.put("Name", parts[0]); resultMap.put("Address", parts[1]); resultMap.put("Email", parts[2]); resultMap.put("PhoneNumber", parts[3]); return resultMap; } public static void main(String[] args) { String input = null; Map<String, String> result = convertToMap(input); System.out.println(result); } }
Ainsi, nous avons une méthode raffinée qui gère diverses erreurs et différents cas de passage de paramètres. Nous avons testé cette méthode manuellement sans utiliser la bibliothèque JUnit. Cependant, dans la section suivante, nous le ferons beaucoup plus rapidement en utilisant cette bibliothèque et des tests unitaires.
Merci pour vos commentaires !