Intégration testant plusieurs dbcontexts de structure Entity partageant une firebase database

Dans mon application, j’ai plusieurs dbcontexts de structure de petite entité qui partagent la même firebase database, par exemple:

public class Context1 : DbContext { public Context1() : base("DemoDb") { } } public class Context2 : DbContext { public Context2() : base("DemoDb") { } } 

Toutes les mises à jour de la firebase database sont effectuées via des scripts et ne dépendent pas des migrations (elles ne le seront pas non plus). La question est la suivante: comment feriez-vous des tests d’intégration dans ces contextes?

Je crois qu’il y a trois options ici (il y en a peut-être plus que je ne les connais pas)

Option 1 – Super contexte – un contexte contenant tous les modèles et toutes les configurations nécessaires à la configuration de la firebase database:

 public class SuperContext : DbContext { public SuperContext() : base("DemoDb") { } } 

Dans cette option, la firebase database de test serait configurée par rapport au super contexte et tous les tests ultérieurs seraient effectués dans des contextes plus petits. La raison pour laquelle je n’aime pas cette option est que je vais dupliquer toutes les configurations et tous les modèles d’entités que j’ai déjà construits.

Option 2 – créez un initialiseur personnalisé pour les tests d’intégration qui exécutera tous les scripts d’initialisation de firebase database appropriés:

 public class IntegrationTestInitializer : IDatabaseInitializer { public void InitializeDatabase(DbContext context) { /* run scripts to set up database here */ } } 

Cette option permet de tester la structure réelle de la firebase database, mais nécessite également une mise à jour à chaque ajout de nouveaux scripts de firebase database.

Option 3 – testez simplement les contextes individuels:

Dans cette option, on laisserait simplement EF créer la firebase database de tests en fonction du contexte et tous les tests opéreraient dans leur propre “bac à sable”. La raison pour laquelle je n’aime pas cela, c’est qu’il ne vous semble pas que vous feriez un test par rapport à une représentation fidèle de la firebase database.

Je me balance actuellement vers les options 2. Qu’en pensez-vous tous? Existe-t-il une meilleure méthode?

J’utilise beaucoup les tests d’intégration, car je pense toujours que c’est le moyen de test le plus fiable lorsque des processus dépendants des données sont impliqués. J’ai également quelques contextes différents et des scripts DDL pour les mises à niveau de la firebase database. Nos situations sont donc très similaires.

Je me suis retrouvé avec l’ option 4 : conserver le contenu de la firebase database de tests unitaires via l’interface utilisateur standard. Bien sûr, la plupart des tests d’intégration modifient temporairement le contenu de la firebase database, dans le cadre de la phase “test” du test (plus d’informations sur ce ” temporaire ” plus tard), mais le contenu n’est pas configuré au démarrage de la session de test.

Voici pourquoi.

À un moment donné, nous avons également généré le contenu de la firebase database au début de la session de test, soit par code, soit en désérialisant les fichiers XML. (Nous n’avions pas encore EF, mais sinon nous aurions probablement eu une méthode Seed dans un initialiseur de firebase database). Graduellement, j’ai commencé à ressentir des doutes avec cette approche. Conserver le code / XML était une tâche ardue lorsque le modèle de données ou la logique métier a changé, en particulier. quand de nouveaux cas d’utilisation ont dû être conçus. Parfois, je me suis permis une corruption mineure de ces données de test, sachant que cela n’affecterait pas les tests.

De plus, les données devaient avoir un sens, car elles devaient être aussi valides et cohérentes que les données de l’application réelle. Une façon de s’assurer de cela consiste à générer les données par l’application elle-même, sans quoi, inévitablement, vous dupliqueriez en quelque sorte la logique métier dans la méthode de départ. Se moquer des données du monde réel est en réalité très difficile. C’est la chose la plus importante que j’ai découverte. Tester des constellations de données qui ne représentent pas de véritables cas d’utilisation n’est pas seulement une perte de temps, c’est une fausse sécurité.

Je me suis donc retrouvé à créer les données de test via le front-end de l’application, puis à sérialiser minutieusement ce contenu en XML ou à écrire un code qui générerait exactement la même chose. Jusqu’au jour où il m’est apparu que les données étaient facilement disponibles dans cette firebase database, pourquoi ne pas les utiliser directement?

Maintenant, peut-être demandez-vous comment rendre les tests indépendants?

Les tests d’intégration, tout comme les tests unitaires, doivent être exécutables séparément. Ils ne doivent pas dépendre d’autres tests et ne doivent pas en être affectés. Je suppose que l’arrière-plan de votre question est que vous créez et créez une firebase database pour chaque test d’intégration. C’est un moyen de réaliser des tests indépendants.

Mais que se passe-t-il s’il n’y a qu’une seule firebase database et aucun script de départ? Vous pouvez restaurer une sauvegarde pour chaque test. Nous avons choisi une approche différente. Chaque test d’intégration s’exécute dans un TransactionScope qui n’a jamais été engagé. C’est très facile d’y parvenir. Chaque appareil de test hérite d’une classe de base dotée de ces méthodes (NUnit):

 [SetUp] public void InitTestEnvironment() { SetupTeardown.PerTestSetup(); } [TearDown] public void CleanTestEnvironment() { SetupTeardown.PerTestTearDown(); } 

et dans SetupTeardown :

 public static void PerTestSetup() { _tranactionScope = new TransactionScope(); } public static void PerTestTearDown() { if (_tranactionScope != null) { _tranactionScope.Dispose(); // Rollback any changes made in a test. _tranactionScope = null; } } 

_tranactionScope est une variable membre statique.

L’option 2, ou toute variante de celle-ci qui exécute les scripts de mise à jour de la firebase database, serait la meilleure solution. Sinon, vous ne testez pas nécessairement l’intégration avec la même firebase database que celle que vous avez en production (du moins en ce qui concerne le schéma).

Afin de résoudre votre problème de mise à jour à chaque ajout de nouveaux scripts de firebase database, si vous deviez conserver tous les scripts dans un seul dossier, éventuellement dans le projet avec une action de construction “copier si plus récent”, vous pouvez les lire par programme. archivez et exécutez le script. Tant que l’emplacement où vous lisez les fichiers est votre référentiel canonique pour les scripts de mise à jour, vous n’aurez jamais besoin d’y aller et d’y apporter des modifications.