Tests unitaires avec Visual Studio (source MSDN)
Rappels (initiation aux tests unitaires SI6 Tp6) Les tests unitaires offrent aux développeurs une méthode rapide pour rechercher des erreurs de logique dans les méthodes des classes des projets Visual C#. Un test unitaire peut être créé une fois et exécuté à chaque modification du code source pour s'assurer qu'aucun bug n'a été introduit.
Procédure pas à pas : création et exécution de tests unitaires Cette procédure pas à pas décrit la création, l'exécution et la personnalisation d'une série de tests à l'aide de Microsoft Visual Studio 201x. Vous commencez avec un projet C# qui est en développement, vous créez des tests qui exercent son code, vous exécutez les tests et vous examinez les résultats. Ensuite, vous pouvez modifier votre code de projet et réexécuter les tests. Dans cette procédure pas à pas, vous effectuerez les tâches suivantes : • • • • •
Préparation du projet « Banque ». Création de tests unitaires. Exécution de ces tests sur le code. Exécuter un test unitaire et corriger le code Créer et exécuter un test unitaire pour une méthode privée
Le projet Banque a pour code : namespace Banque { public class CompteBancaire { private string nomClient; private double solde; private bool bloque = false; public CompteBancaire(string unNomClient, double unSolde) { nomClient = unNomClient; solde = unSolde; } public string getNomClient() {
SIO2
SLAM4– Tp tests unitaires
1
return nomClient; } public double getSolde() { return solde; } public void Debit(double unMontant) { if (bloque) { throw new Exception("Compte bloqué"); } if (unMontant > solde) { throw new ArgumentOutOfRangeException("unMontant"); } if (solde < 0) { throw new ArgumentOutOfRangeException("unMontant"); } solde += unMontant; } public void Credit(double unMontant) { if (bloque) { throw new Exception("Compte bloqué"); } if (unMontant < 0) { throw new ArgumentOutOfRangeException("unMontant"); } solde += unMontant; } private void CompteBloque() { bloque = true; } private void CompteDebloque() { bloque = false; } } }
Remarque : l'unique erreur intentionnelle de cet échantillon est qu'un signe moins (et non plus) doit se situer devant le signe égal (dans la méthode Debit « solde += unMontant ; »).
Préparation du projet Banque 1. Ouvrir Visual Studio 201x, choisir Nouveau projet. 2. Dans la liste de types d'applications, cliquer sur Bibliothèque de classes. 3. Dans la zone Nom, taper Banque et choisir l’emplacement, puis cliquer sur OK. SIO2
SLAM4– Tp tests unitaires
2
4. Le nouveau projet Banque est créé et affiché dans l'Explorateur de solutions, avec le fichier Class1.cs ouvert dans l'éditeur de code. 5. Copier le code source de la classe CompteBancaire dans le contenu de Class1. 6. Renommer Class1.cs en CompteBancaire.cs (Explorateur de solutions, clic droit). 7. Ajouter un nouveau projet à votre solution de type Application Console : BanqueConsole. 8. Rajouter dans les Références de BanqueConsole, la bibliothèque Banque : clic droit sur Références/ Ajouter une référence. 9. Tester la classe CompteBancaire avec les lignes de code suivantes : static void Main(string[] args) { CompteBancaire unCB = new CompteBancaire("M.Test Unitaire", 15); unCB.Credit(5); unCB.Debit(12); Console.WriteLine("Solde actuel : " + unCB.getSolde()); }
Remarque : rajouter la ligne using Banque ; et vérifier le projet de démarrage de la solution (clic droit/Propriétés) Vous avez maintenant un projet nommé Banque. Il contient la classe publique CompteBancaire, dont vous testerez les méthodes dans les procédures suivantes.
Création de tests unitaires 1. Dans la classe CompteBancaire, cliquer avec le bouton droit sur la méthode Debit() et sélectionner : Créer des tests unitaires. La boîte de dialogue Créer des tests unitaires s'affiche. Sous Sélection actuelle, une arborescence affiche la hiérarchie de classes et de membres de l'assembly qui héberge la classe CompteBancaire. Vous pouvez utiliser cette page pour générer des tests unitaires pour toute sélection de ces membres et pour choisir un projet de test dans lequel vous souhaitez placer les tests unitaires générés. Dans l'arborescence, seule la méthode Debit() est sélectionnée. Laisser-la sélectionnée et sélectionner également la méthode Credit(). 2. Pour Projet de sortie, sélectionner : Créer un nouveau projet de test Visual C#.
SIO2
SLAM4– Tp tests unitaires
3
3. Cliquer sur Paramètres. La boîte de dialogue Paramètres de génération des tests s'affiche. Sous Paramètres d'affectation de nom, vous pouvez modifier la manière dont les fichiers de test, les classes de test et les méthodes de test sont nommés à mesure qu'ils sont générés. Sous Général, vous pouvez modifier d'autres aspects de génération de test. Conserver les valeurs par défaut de ces paramètres, puis cliquer sur OK.
4. Dans la boîte de dialogue Créer des tests unitaires, cliquez sur OK. La boîte de dialogue Nouveau projet de test s'affiche. 5. Donner le nom BanqueTest, puis cliquer sur Créer. SIO2
SLAM4– Tp tests unitaires
4
Cela crée un projet nommé BanqueTest, qui est affiché dans l'Explorateur de solutions. Un fichier nommé CompteBancaireTest.cs, qui contient une classe de test, est ajouté à BanqueTest. La classe est renseignée avec une propriété TestContext et des méthodes permettant de tester les méthodes Debit() et Credit(). Remarque : L'attribut [TestMethod()] est assigné automatiquement à chaque méthode de test. Chaque test correspond à une seule méthode du code à tester. Les méthodes de test sont hébergées dans une classe de test à laquelle est assigné l'attribut [TestClass()]. 6. Dans CompteBancaireTest.cs, spécifier les valeurs des variables à tester. Accéder à la méthode DebitTest, où trois lignes // TODO indiquent les variables à définir. 7. Pour connaître les valeurs à utiliser pour la méthode DebitTest, ouvrir le fichier Program.cs du projet BanqueConsole. Noter que le nom de client est initialisé avec M. Test Unitaire, le solde de compte est initialisé avec 15, la méthode Credit est appelée avec le paramètre 5 et la méthode Debit est appelée avec le paramètre 12. Par conséquent, si ce compte démarre avec un solde de 15 et un crédit de 5, un appel à la méthode Debit en passant 12 doit produire un nouveau solde de 8. Vous utiliserez cette valeur Solde attendue (8) plus loin. 8. Dans le fichier CompteBancaireTest.cs, accéder à la méthode DebitTest. 9. Définissez les valeurs suivantes (lignes //TODO) :
SIO2
SLAM4– Tp tests unitaires
5
10. Dans la méthode CreditTest, ajouter les valeurs suivantes :
11. Enregistrer le fichier CompteBancaireTest.cs. Vous avez créé un fichier de code source qui contient des tests pour le projet Banque. Vous êtes maintenant prêt à exécuter les tests de la classe CompteBancaireTest.
Exécution de ces tests sur le code 1. Dans le menu Test, cliquer sur Fenêtres et sélectionner Affichage des tests. La fenêtre Affichage des tests s'affiche. 2. Cliquer avec le bouton droit sur DebitTest, puis cliquer sur Exécuter la sélection. Dans la colonne Résultat de la fenêtre Résultats des tests, l'état du test s'affiche comme étant « En cours d'exécution » lorsque le test s'exécute. Une fois l'exécution du test terminée, le résultat devient Non concluant.
3. Dans la fenêtre Résultats des tests, cliquer avec le bouton droit sur la ligne qui représente le test, puis cliquer sur Afficher les détails des résultats des tests. 4. La page Détails des résultats des tests contient le message d'erreur « Échec d'Assert.Inconclusive ». Une méthode qui ne retourne pas une valeur ne peut pas être vérifiée. Pour créer un test réussi, commencer par rechercher et évaluer cette instruction Assert. 5. Pour rechercher la méthode de test qui contient l'instruction Assert, ouvrir le fichier CompteBancaireTest.cs et accéder à la méthode DebitTest(). L'instruction Assert est la dernière ligne de la méthode DebitTest. Elle se présente comme suit : Assert.Inconclusive("Une méthode qui ne retourne pas une valeur ne peut pas être vérifiée.");
Transformer cette instruction Assert en commentaire. Réactualiser le test avec dans Affichage des tests. 6. Si vous exécutiez maintenant le test, il donnerait un résultat Réussite, mais uniquement car il ne testerait rien. Vous devez ajouter du code qui teste les résultats attendus.
SIO2
SLAM4– Tp tests unitaires
6
7. Ajouter l'instruction suivante à la fin de la méthode DebitTest : Assert.AreEqual((System.Convert.ToDouble(3)), target.solde);
Cette instruction compare le résultat attendu (3, solde initial 15 et débit de 12) avec le résultat réel d'un appel à la méthode Debit de la classe CompteBancaire. Si les deux valeurs sont inégales, l'instruction Assert retourne False, ce qui fait échouer le test.
Vous avez exécuté la méthode DebitTest générée de votre classe de test CompteBancaireTest, remarquez qu'elle nécessitait des modifications.
Exécuter un test unitaire et corriger le code 1. Exécuter de nouveau le test Debit : dans le fichier CompteBancaireTest.cs, cliquer avec le bouton droit sur la méthode DebitTest () puis cliquer sur Exécuter les tests. Une fois l'exécution du test terminée, le résultat devient Échec. La différence de valeurs semble indiquer une opération mathématique incorrecte dans la méthode Debit de la classe CompteBancaire. 2. Ouvrir le fichier CompteBancaire.cs et accéder à la méthode Debit. Remarquer l'assignation suivante : solde += unMontant; Cette assignation ajoute un montant à un solde alors que, dans une méthode Debit, elle devrait soustraire. Modifier cette ligne comme suit : solde -= unMontant;
Réexécuter le test Debit. La colonne Résultat de la fenêtre Résultats des tests affiche
Réussite pour DebitTest. Remarque : Vous n'avez pas eu à régénérer le projet de test après avoir modifié le code source, car l'exécution d'un test en mode silencieux génère le projet. Vous avez créé un test unitaire qui fonctionne et, grâce à lui, vous avez trouvé et corrigé une erreur dans votre code. 3. Tester la méthode Credit(), en effectuant d’éventuelles modifications. SIO2
SLAM4– Tp tests unitaires
7
Créer et exécuter un test unitaire pour une méthode privée 1. Ouvrir le fichier CompteBancaire.cs dans le projet Banque. 2. Cliquer avec le bouton droit sur la méthode CompteBloque() et sélectionner Créer des tests unitaires. La boîte de dialogue Créer des tests unitaires s'affiche. Dans l'arborescence affichée, seule la méthode CompteBloque() est sélectionnée. 3. Cliquer sur Filtre, puis effacer Afficher les éléments non publics. Noter que la méthode CompteBloque() est supprimée dans la liste de méthodes enfants de la classe CompteBancaire. Rétablir l’affichage de la méthode CompteBloque(), puis cliquer sur OK. Cela permet de créer un fichier d'accesseur private dénommé Banque.accessor qui contient des méthodes d'accesseur spéciales utilisées par le test pour appeler indirectement des méthodes privées dans la classe CompteBancaire. Le nouveau fichier est affiché dans l'Explorateur de solutions, dans le dossier Références de test.
4. Ouvrir le fichier CompteBancaireTest.cs et accéder à la méthode CompteBloqueTest(). 5. Modifier le code de la méthode CompteBloqueTest() de sorte qu'il se présente comme suit :
SIO2
SLAM4– Tp tests unitaires
8
public void CompteBloqueTest() { //PrivateObject param0 = null; // TODO: initialisez à une valeur appropriée CompteBancaire_Accessor target = new CompteBancaire_Accessor("M. Test Unitaire",15); // TODO: initialisez à une valeur appropriée target.CompteBloque(); // Assert.Inconclusive("Une méthode qui ne retourne pas une valeur ne peut pas être vérifiée."); bool CompteCredite = true; // False correspond à un compte non crédité // Tentative de crédit d'un compte try { target.Credit(5); } catch (System.Exception) { // Threw exception. CompteBloque s'exécute correctement. CompteCredite = false; } // Assertion échoue si 'CompteCredite' est false. Echec du test. Assert.IsTrue(CompteCredite, "compte non crédité"); }
6. Exécuter le test CompteBloqueTest. Expliquer le résultat obtenu :
SIO2
SLAM4– Tp tests unitaires
9