web-dev-qa-db-fra.com

TDD avec des fonctions SQL et de manipulation de données

Pendant que je suis un programmeur professionnel, je n'ai jamais été formellement formé à l'ingénierie logicielle. Comme je suis fréquemment visité ici et j'ai donc remarqué une tendance à la rédaction des tests de l'unité chaque fois que possible et, comme mon logiciel devient plus complexe et sophistiqué, je vois des tests automatisés comme une bonne idée du débogage.

Cependant, la plupart de mes travaux impliquent la rédaction de SQL complexe, puis le traitement de la production d'une manière ou d'une autre. Comment écririez-vous un test pour vous assurer que votre SQL renvoie les données correctes, par exemple? Ensuite, disons si les données n'étaient pas sous votre contrôle (par exemple, celle d'un système tiers), comment pouvez-vous tester efficacement vos routines de traitement sans avoir à remédier à des pousses de données factices?

La meilleure solution que je puisse penser concerne la vue des données qui, ensemble, couvrent la plupart des cas. Je peux ensuite rejoindre ces points de vue avec mon SQL pour voir s'il renvoie les bonnes dossiers et traiter manuellement les vues pour voir si mes fonctions, etc. font ce qu'ils sont censés. Néanmoins, cela semble excessive et facilesse; En particulier trouvant des données à tester contre ...

14
Xophmeister

Une règle importante pour tester tout ce qui est liée à la base de données est de l'isoler complètement du reste de votre application.

Les ports et adaptateurs L'architecture est un très bon exemple. La base de données est considérée comme un plugin externe via un adaptateur à votre application. Il en va de même avec tous les sous-systèmes tiers. Pour tester la manière dont votre application se comporterait et interpréterait les réponses des sous-systèmes tierces, la seule façon de savoir comment tester les réponses de ce sous-système individuel. Je ne veux pas nécessairement que vous deviez écrire manuellement tous les objets de données. Vous pouvez facilement prendre l'approche d'utiliser des tests basés sur les données.

En ce qui concerne les tests sur la manière dont votre application interagit avec votre base de données, vous pouvez simuler les adaptateurs de base de données pour utiliser une base de données en mémoire par exemple.

Test maintenant tes requêtes de base de données. Tout d'abord, toutes les requêtes complexes doivent être décomposées dans des requêtes plus faciles, simples et prévisibles. Le même que vous le feriez pour une classe grasse ou pour une fonction grasse. Il existe des outils pouvant vous aider à tester votre base de données comme dbunit . Une approche simple que je prends parfois est d'utiliser le concept de tests de caractérisation. Je mettrais donc la base de données dans un état de connaissement, exécutez toutes les questions que je dois écrire enregistrer la sortie dans un lieu (fichier, mémoire) et considérez cette sortie pour être la bonne. Les prochaines exécutions compareraient leur rendement avec celui-ci, de sorte que cela m'offrirait certainement les tests de régression dont j'ai besoin. En effet, la première sortie n'est pas garantie d'être correcte, mais le problème de la régression peut être résolu de cette façon. Si vous avez vos requêtes bien décomposées, vous pouvez les tester individuellement vers la base de données dans un état connu.

6
Vadim

C'est une question intéressante car la base de données est généralement la pièce qui est façonnée pendant les tests d'unités d'application. Espérons que la logique du moteur de base de données elle-même est bien testée par le fournisseur, mais bien sûr, les requêtes, le schéma et les procédures stockées sont du code qui doivent être testés et protégés contre la régression. Ceci est souvent laissé au test d'intégration qui n'est pas TDD.

Les points de vue seraient probablement un moyen difficile de le faire car ils ne prêtent pas vraiment à l'essai premier test automatique rouge-lumière, essai automatique d'un aspect par test qui est préféré dans TDD. Aussi avec des vues, vous ne pouvez pas d'abord écrire le test avant le code. Une meilleure approche consisterait à écrire des procédures stockées dans lesquelles vous pouvez ajouter une logique "affirmation" dans la procédure (par exemple en utilisant des instructions "si") pour tester la sortie de défaillance. Vous devez rechercher une seule chose dans chaque test de l'unité pour isoler l'appareil, et le SP méthode serait mieux adapté à cela. Aussi, avec SP, vous pouvez exécuter toute la suite d'entre elles comme scripts Lorsque vous développez le code initial et plus tard lors du test de régressions lors du refactoring.

Aussi, soyez conscient que les tests doivent être répétables et que vous aurez besoin de scripts pour initialiser et déchirer l'état de la base de données pour vous assurer que l'état est identique à chaque test de l'unité.

Pour votre question sur les données qui ne sont pas sous votre contrôle, c'est un domaine difficile. Je pense que vous feriez mieux de se moquer de la moqueur avec de fausses données et de tester les conditions d'exception et d'avance autant que possible pour les tests d'unités. Sinon, il tombera davantage dans la catégorie des tests d'intégration (qui est également une bonne chose à faire). Pour les tests d'intégration, vous pouvez exécuter vos tests contre les données tiers et la laisser générer une sortie initiale et pour les tests ultérieurs (par exemple après refactoring), assurez-vous que ces sorties répètent la sortie connue initiale.

3
Turnkey

À un moment donné, vous aurez besoin de données de test. Si vous utilisez un système tiers, le schéma a déjà été créé, mais vous devrez aborder les changements futurs. Espérons que vous pouvez obtenir ces modifications de la documentation de mise à niveau, mais vous pouvez être obligé de comparer vous-même des versions de base de données.

Les ensembles de résultats attendus peuvent être enregistrés dans des tables de base de données ou des fichiers externes/feuilles de calcul. J'ai même vu checksum utilisé ou comparaison. Lorsque vous testez une vue/SproC, vous obtiendrez un échec puisqu'il n'existe pas. Ensuite, vous créez l'objet avec suffisamment de code pour exécuter au moins (SELECT -1 comme [mal_data];) et vous obtiendrez une défaillance car elle ne correspond pas au jeu de résultats. Une fois qu'ils correspondent, vous avez votre Greenlight.

J'ai commencé à travailler avec les propriétaires de projets et à leur demander de se moquer de rapports dans une feuille de calcul et d'essayer de trouver des données partielles pour moi (vous pouvez mettre les données de résultat dans une table d'essai.). Il y avait d'abord quelques recrues, mais ils ont réalisé que je vais créer un rapport et ils vont devoir le vérifier de toute façon. Cela a économisé le temps à long terme. S'ils veulent faire une demande de changement, ils deviennent refaire la feuille de calcul. Maintenant, ils peuvent répondre à la question ", quel que soit le dur serait d'ajouter ...?"

1
JeffO