Tests unitaires SQLIte
Bonjour,
Je voudrais faire des tests unitaires sur ma base SQLite. J'ai une classe manager qui gère tous les accès à la base. ( Ecriture, requête && réponse).
Je veux par exemple enregistrer une donnée et m'assure qu'elle est bien dans ma base et qu'elle a la bonne valeur. Pour cela je pense faire qu'a chaque test je crée ma base de donnée complète et à la fin de test supprimer la base, mais si je fais ça j'en suis sur que mes tests vont être très longs parce que c'est une grosse base de donnée. ( J'ai pas encore testé mais je suppose que ça va être long si j'exécute une 100 de tests ou plus par exemple).
Comment vous auriez fait ? ( Je suppose que ç'est la même problématique que CoreData ?)
Merci
PS : Utiliser CoreData vs SQLite est autre sujet déjà discuté sur le forum
Réponses
Avec Core Data, il est possible d'utiliser un stockage "in memory". Donc, je ne crée pas de BdD sur le disque, je teste entièrement en mémoire ce qui revient au même.
Je vois plusieurs solutions à ton problème:
1) à chaque test, tu créerais une base vide (pourquoi travailler sur base remplie?), qui ne sert qu'au test, et tu la supprimerais à la fin du test. Inconvénients: probablement la lenteur, nécessité de lancer des requêtes pour voir le résultat.
2) tu ferais en sorte que ton DBManager se conforme à un protocole DBAccess, qui comprendrait les méthodes pour lire, écrire et lancer des requêtes. Tu pourrais alors créer une classe qui se conforme à ce protocole; par exemple, cette classe pourrait mémoriser tous les appels qui ont été faits.
Inconvénients: c'est du boulot à mettre au point, il faudra commencer par les test unitaires sur cette classe. On ne teste pas sur une BdD réelle, alors il est possible que certaines actions fonctionnent en simulation, mais pas quand on lance de vraies requêtes.
3) de manière similaire, tu pourrais mocker DBManager, pour tester l'ordre des requêtes et leurs arguments.
Inconvénients: l'intégration d'OCMock ne fonctionne jamais du premier coup dans mon expérience, même en utilisant Cocoapods. Même problème de simu que ci-dessus.
Je pense que la 3ème solution est la meilleure dans ton cas.
A priori, j'aurais essayé de faire exactement comme tu dis car c'est le plus simple
Avec un store in memory, cela sera plus rapide. Enfin, cela dépend ce que tu appelles grosse base.
Mais ce que tu décris est plutôt un test modulaire. Pour un test unitaire, je ne suis pas certain que tu aies besoin de toute la base, ne peux-tu pas tester ton manager méthode par méthode avec une base réduite ?
Ou si tu as vraiment besoin de toute la base, tu peux très bien partir de base déjà construites. Ou construire la base au lancement de ta session de tests, puis utiliser une copie pour chaque test.
Pour tous nos tests sur les opérations d'enregistrement CoreData, nous utilisons une base CoreData "InMemory" pendant les tests (alors que l'app utilise une base CoreData fichier, persistée à chaque lancement, ce dont on n'a pas besoin pendant les tests et ce qui nous permet de de pas polluer la vraie base et de toujours partir d'une base vierge)
Du coup avec CoreData on n'a pas vraiment ce problème (et là on a un projet où on utilise Realm et c'est pareil, on utilise un Realm "inMemory" pour les tests qui ne sauve du coup pas sur disque) que tu as avec SQLite.
Bonjour,
Merci pour vos réponses.
Oui je vais partir sur ça, une base réduite pour chaque test.
Test modulaire ? Je ne sais pas, j'ai jamais entendu parler de ça . En tous cas je veux tout tester.