Est-ce une mauvaise pratique d'exécuter des tests sur une base de données plutôt que sur de faux référentiels?

StackOverflow https://stackoverflow.com/questions/607620

Question

Je connais les avantages et j'utilise de fausses données lorsque je travaille avec des systèmes plus complexes.

Et si je développe quelque chose de simple et que je peux facilement configurer mon environnement dans une vraie base de données et que les données auxquelles on accède sont si petites que le temps d'accès n'est pas un facteur et que je n'exécute que quelques tests.

Est-il toujours important de créer de fausses données ou puis-je oublier le codage supplémentaire et passer directement à la réalité?

Lorsque je disais «vraie base de données», je ne parle pas de base de données de production, mais de base de test, mais d’un vrai SGBD vivant et du même schéma que la vraie base de données.

Était-ce utile?

La solution

Les raisons d'utiliser de fausses données au lieu d'une vraie base de données sont les suivantes:

  1. Vitesse. Si vos tests sont lents, vous ne les exécuterez pas. En se moquant de la base de données, vos tests peuvent être exécutés beaucoup plus rapidement qu’ils ne le pourraient autrement.
  2. Contrôle. Vos tests doivent être la source unique de vos données de test. Lorsque vous utilisez de fausses données, vos tests choisissent les faux que vous utiliserez. Il n’ya donc aucune chance que vos tests soient gâchés parce que quelqu'un a quitté la base de données dans un état inconnu.
  3. Ordre de l'indépendance. Nous voulons que nos tests soient exécutables dans n'importe quel ordre. L'entrée d'un test ne doit pas dépendre de la sortie d'un autre. Lorsque vos tests contrôlent les données de test, ils peuvent être indépendants les uns des autres.
  4. Indépendance de l'environnement. Vos tests doivent être exécutables dans n'importe quel environnement. Vous devriez pouvoir les utiliser dans le train, dans l'avion, à la maison ou au travail. Ils ne devraient pas dépendre de services externes. Lorsque vous utilisez de fausses données, vous n'avez pas besoin d'une base de données externe.

Maintenant, si vous construisez une petite application, et en utilisant une vraie base de données (comme MySQL), vous pouvez atteindre les objectifs ci-dessus, puis utilisez bien sûr la base de données. Je fais. Mais ne vous y trompez pas, au fur et à mesure que votre application se développe, vous serez éventuellement confronté à la nécessité de simuler la DB. C'est bon, faites-le quand vous en avez besoin. YAGNI. Assurez-vous juste de le faire QUAND vous en avez besoin. Si vous le laissez partir, vous paierez.

Autres conseils

Cela dépend en quelque sorte de ce que vous voulez tester. Souvent, vous souhaitez tester la logique réelle de votre code et non les données de la base de données. Il est donc inutile de mettre en place une base de données complète pour exécuter vos tests.

Prenez également en compte la quantité de travail nécessaire pour la maintenance de vos tests et de votre base de données test. Tester votre code avec une base de données signifie souvent que vous testez votre application dans son ensemble et non les différentes parties isolément. Cela nécessite souvent beaucoup de travail pour maintenir la base de données et les tests synchronisés.

Et le dernier problème est que le test doit être exécuté de manière isolée. Chaque test doit donc être exécuté sur sa propre version de la base de données ou le laisser dans le même état qu’il était avant l’exécution du test. Ceci inclut l'état après un test ayant échoué.

Ceci dit, si vous voulez vraiment tester votre base de données, vous pouvez le faire. Il existe des outils d'aide à la configuration et à la suppression d'une base de données, tels que dbunit .

J'ai vu des gens essayer de créer un test unitaire comme celui-ci, mais il s'avère presque toujours plus de travail que de valeur. La plupart l'ont abandonné à mi-parcours pendant le projet, la plupart le laissant complètement, pensant que l'expérience serait transférée aux tests unitaires en général.

Je recommanderais donc de garder les tests simples et isolés et d'encapsuler votre code suffisamment bon pour qu'il soit possible de tester votre code de manière isolée.

Je pense que cela dépend de si vos requêtes sont résolues dans le référentiel (meilleure option, IMO) ou si le référentiel expose des requêtes pouvant être composées. par exemple, si vous avez une méthode de référentiel:

IQueryable<Customer> GetCustomers() {...}

Ensuite, votre interface utilisateur peut demander:

var foo = GetCustomers().Where(x=>SomeUnmappedFunction(x));

bool SomeUnmappedFunction(Customer customer) {
   return customer.RegionId == 12345 && customer.Name.StartsWith("foo");
}

Cela passera pour un faux référentiel basé sur un objet, mais échouera pour les implémentations effectives de la base de données. Bien sûr, vous pouvez l'annuler en laissant le référentiel gérer toutes les requêtes en interne (pas de composition externe); par exemple:

Customer[] GetCustomers(int? regionId, string nameStartsWith, ...) {...}

Comme cela ne peut pas être composé, vous pouvez vérifier la base de données et l'interface utilisateur indépendamment. Avec les requêtes composables, vous êtes obligé d'utiliser des tests d'intégration si vous voulez que cela soit utile.

Cela dépend plutôt de savoir si la base de données est automatiquement configurée par le test, ainsi que si la base de données est isolée des autres développeurs.

Pour le moment, cela ne pose peut-être pas de problème (par exemple, un seul développeur). Cependant (pour la configuration manuelle de la base de données), la configuration de la base de données est un obstacle supplémentaire à l'exécution de tests, ce qui est une très mauvaise chose.

Si vous écrivez simplement une simple application unique dont vous savez pertinemment qu'elle ne se développera pas, je pense à de nombreuses "meilleures pratiques". allez juste par la fenêtre.

Vous n'avez pas besoin d'utiliser DI / IOC, de faire des tests unitaires ou de simuler votre accès à la base de données si tout ce que vous écrivez est simple: "Contactez-nous". forme. Cependant, où tracer la ligne entre un "simple" et app et un "complexe" on est difficile.

En d'autres termes, utilisez votre meilleur jugement car il n'y a pas de réponse définitive à cette question.

Vous pouvez le faire pour le scénario, tant que vous ne les voyez pas comme "unité". tests. Ce sont des tests d'intégration. Vous souhaitez également déterminer si vous effectuerez des tests manuels dans l'interface utilisateur à plusieurs reprises, car vous pourriez automatiser vos tests de détection de la fumée à la place. Cela étant dit, vous pourriez même envisager de ne pas effectuer les tests d'intégration et de travailler uniquement au niveau des tests fonctionnels / d'interface utilisateur (car ils couvriront déjà l'intégration).

Comme d’autres, comme il a été souligné, il est difficile de tracer une ligne de démarcation entre complexe et non complexe, et vous le feriez normalement maintenant quand il est trop tard :(. Si vous êtes déjà habitué à le faire, je suis sûr que vous avez gagné ». Si cela n’était pas le cas, vous pourriez en tirer des leçons:)

Dans la mesure où la Real DB ne vous gêne pas et que vous pouvez aller plus vite de cette façon, je voudrais être pragmatique et aller de l'avant.

Dans le test unitaire, le " test " est plus important que "l'unité".

En supposant que vous souhaitiez automatiser cette opération, le plus important est que vous puissiez générer par programme votre condition initiale. Il semble que ce soit le cas et, mieux encore, vous testez des données réelles.

Cependant, il existe quelques inconvénients:

Votre vraie base de données peut ne pas couvrir certaines conditions de votre code. Si vous disposez de fausses données, vous provoquez ce comportement.

Et comme vous le soulignez, vous avez une application simple; quand cela deviendra moins simple, vous voudrez avoir des tests que vous pouvez classer en tant que tests unitaires et tests système. Les tests unitaires doivent cibler une simple fonctionnalité, ce qui sera beaucoup plus facile à utiliser avec de fausses données.

Un des avantages des faux référentiels est que vos tests de régression / unité sont cohérents, car vous pouvez vous attendre aux mêmes résultats pour les mêmes requêtes. Cela facilite la création de certains tests unitaires.

Il y a plusieurs inconvénients si votre code (s'il n'est pas en lecture seule) modifie des données: - Si vous rencontrez une erreur dans votre code (ce qui explique probablement pourquoi vous testez), vous risquez de détruire la base de données de production. Même si vous ne l'avez pas cassé. - Si la base de données de production change au fil du temps, et particulièrement pendant l'exécution de votre code, vous risquez de perdre la trace du matériel de test que vous avez ajouté et d'avoir du mal à le supprimer ultérieurement de la base de données. - Les requêtes de production d'autres systèmes accédant à la base de données peuvent traiter vos données de test comme de vraies données, ce qui peut corrompre les résultats de processus métier importants. Par exemple, même si vous avez marqué vos données avec un indicateur ou un préfixe spécifique, pouvez-vous assurer que toute personne accédant à la base de données adhérera à ce schéma?

De plus, certaines bases de données sont régies par les lois sur la confidentialité. Par conséquent, en fonction de votre contrat et du propriétaire de la base de données principale, vous pouvez être légalement autorisé à accéder à de vraies données.

Si vous devez exécuter une base de données de production, nous vous recommandons d’exécuter une copie que vous pouvez facilement créer pendant les heures de pointe.

C'est une application très simple, et vous ne pouvez pas la voir grandir, je ne vois aucun problème à exécuter vos tests sur une vraie base de données. Si, toutefois, vous pensez que cette application va évoluer, il est important que vous en teniez compte dans vos tests.

Faites en sorte que tout soit aussi simple que possible et, si vous avez besoin ultérieurement de tests plus souples, faites-le. Toutefois, planifiez à l’avance, car vous ne voulez pas avoir une énorme application dans 3 ans qui repose sur des tests anciens et hacky (pour une application volumineuse).

Les inconvénients de l'exécution de tests sur votre base de données sont le manque de rapidité et la complexité de la configuration de l'état de votre base de données avant l'exécution des tests.

Si vous en avez le contrôle, l'exécution des tests directement sur la base de données ne pose aucun problème. c'est en fait une bonne approche car elle simule mieux votre produit final que l'utilisation de fausses données. La solution consiste à adopter une approche pragmatique et à considérer les meilleures pratiques comme des directives et non comme des règles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top