Dans ce chapitre, nous allons écrire les premiers tests unitaires pour valider le modèle de CoinCoinTracker. Le modèle ? Quel modèle ? Eh oui, rappelez-vous : nous privilégions une approche TDD, nous commençons donc par écrire les tests unitaires. Nous écrirons ensuite le code du modèle pour valider ces tests.
Pour rappel, CoinCoinTracker est une application de gestion de porte-monnaie virtuel. Au lieu de mettre des vraies pièces dans votre porte-monnaie, vous allez ajouter de l'argent via cette application mobile. Rien d'extraordinaire, mais grâce à cette application, je suis sûr que vous vous sentirez plus riche !
Identifiez les fonctionnalités de votre application
Avant d'écrire les tests pour valider notre modèle, posez-vous la question : quelles sont les fonctionnalités offertes par mon modèle ? Quelques réponses possibles :
Mettre de l'argent dans le porte-monnaie.
Retirer de l'argent du porte-monnaie.
Consulter la somme disponible dans le porte-monnaie.
Nous pourrons également tester certains comportements, tels que :
Ne pas pouvoir retirer plus que le montant disponible (cela paraît évident, mais c'est important !).
Ne pas ajouter plus qu'un certain montant (cela reste un porte-monnaie, ce n'est pas un compte bancaire !).
Écrivez les tests
Renommez le fichier ExampleUnitTest
Lancez Android Studio, puis rendez-vous dans le paquetage des tests (celui se terminant par (test)). Commençons par renommer le fichier ExampleUnitTest :
faites un clic droit sur le fichier ;
sélectionnez Refactor > Rename... ;
renommez-le WalletUnitTest ;
laissez toutes les cases cochées puis cliquez sur le bouton Refactor.
Créez le porte-monnaie
Ouvrez le fichier, puis localisez la méthode addition_isCorrect(). Renommez-la en testWalletIsCreated(). Cette méthode va nous permettre de valider le fait de créer le porte-monnaie en l'initialisant avec un certain montant.
Le test va donc effectuer les appels suivants :
Créer une instance de porte-monnaie avec un certain montant.
Vérifier que la somme contenue dans le porte-monnaie est correcte.
Supprimez le code existant de l'ancienne méthode, puis écrivez le code de test comme si la classe Wallet existait :
@Test
public void testWalletIsCreated() throws Exception {
// Create a new Wallet instance, with 42 EUR in it
Wallet wallet = new Wallet(42);
// Check that the wallet actually contains 42 EUR
assertEquals(42, wallet.getBalance(), 0.001);
}
Quelques précisions sur ce code :
La directive @Test au-dessus de la méthode est une annotation Java. Cette annotation est interprétée par JUnit pour savoir que cette méthode est une méthode de test. Il existe d'autres annotations connues de JUnit, telles que @Before ou @After. Ces annotations permettent d'initialiser des données pour le test, puis de tout nettoyer à la fin du test. N'hésitez pas à consulter la documentation pour avoir davantage d'informations.
Le troisième paramètre de la méthode assertEquals() permet d'éviter les erreurs de comparaison dans le cas des nombres décimaux. Ici, nous spécifions que nous souhaitons une précision à trois chiffres après la virgule, ce qui est suffisant dans notre cas.
Vous devriez avoir quelques mots en rouge : c'est normal, car la classe Wallet n'existe pas encore, et ses méthodes non plus. Mais vous pouvez déjà constater une chose : pour que le test fonctionne, il vous suffit de créer une classe Wallet, avec un constructeur permettant d'initialiser sa valeur. Ensuite, une seule méthode est nécessaire : celle pour récupérer la somme contenue dans le porte-monnaie.
D'ailleurs, c'est un excellent exercice que je vous invite à faire tout de suite : implémentez la classe Wallet. N'oubliez pas : ne codez que le strict nécessaire pour que le test soit valide. Dès que le test s'exécute avec succès, bravo ! Si vous éprouvez quelques difficultés, n'hésitez pas à consulter mon implémentation GitHub.
Mettez de l'argent dans le porte-monnaie
De la même façon, nous allons ajouter une nouvelle méthode de test pour valider le fait de retirer de l'argent du porte-monnaie. Pour ce faire, positionnez-vous dans la classe WalletUnitTest puis utilisez la fonctionnalité de génération d'Android Studio, en tapant ⌘ + N sur Mac ou ALT + Insert sur Windows et Linux. Puis sélectionnez l'option Test Method. Nommez-la depositMoney().
Le test va effectuer les appels suivants :
Créer une instance de porte-monnaie.
Ajouter une somme au porte-monnaie.
Vérifier que la somme a bien été prise en compte.
Implémentez le test de cette façon :
@Test
public void testDepositMoney() throws Exception {
// Create a new Wallet instance, with 0 EUR in it
Wallet wallet = new Wallet(0);
// Put 10 EUR in the wallet
wallet.deposit(10);
// Check that the wallet actually contains the 10 EUR
assertEquals(10, wallet.getBalance(), 0.001);
}
Comme vous le constatez, la méthode deposit() n'existe pas. Parfait, il vous suffit donc de l'implémenter ! Cette méthode doit permettre de déposer dans le porte-monnaie la somme passée en paramètre.
Retirez de l'argent du porte-monnaie
Ajoutons également une nouvelle méthode de test pour valider le fait de retirer de l'argent du porte-monnaie. Créez une nouvelle méthode nommée withdrawMoney() et écrivez le test correspondant. Vous allez vous apercevoir que la classe Wallet a besoin d'une méthode permettant de récupérer de l'argent (que vous pouvez nommer withdraw()). Je vous propose de l'implémenter vous-même également. Mon implémentation GitHub est là pour vous aider, au cas où.
En résumé
Dans l’approche TDD, nous commençons par écrire les tests avant d’écrire le code de notre application.
Avant d’écrire les tests (et donc le code), pensez aux fonctionnalités dont vous aurez besoin pour savoir quel type de tests vous aurez à écrire.
Vous savez désormais comment écrire des tests unitaires. Apprenez à les automatiser dans le chapitre suivant. 😀