Skip to content

Tests du backend ​

Tests unitaires par couche et tests d'intégration traversant la chaîne complète, du bit Modbus jusqu'au DTO poussé à l'interface. 155 fichiers, 1263 méthodes de test.

TechnologiexUnit, FluentAssertions, Moq, Xunit.SkippableFact
BasesEF Core InMemory, et SQLite là où un fournisseur relationnel est requis
Hôte HTTPMicrosoft.AspNetCore.Mvc.Testing — WebApplicationFactory<Program>
Référence projetdotnet/backend — qui lui ouvre ses types internes par InternalsVisibleTo

Structure ​

Le découpage suit celui du backend, plus un dossier d'intégration qui traverse les couches.

DossierFichiersMéthodesContenu
Domain/11118Entités, modèles et objets valeur
Application/50506Services métier, DTO, sécurité, rapports
Infrastructure/37208Transport Modbus, adaptateurs, persistance, télémétrie
Presentation/30313Contrôleurs et hub temps réel
Integration/14101Chaînes complètes
Repositories/314Accès aux données
Shared/13Configuration applicative partagée
TestHelpers/6—Client Modbus en mémoire, harnais RTU sur tube nommé, constructeur de scénarios, faux journal d'audit, décodeur JWT, déclaration d'environnement

À la racine : TestDatabaseFixture.cs (base InMemory par identifiant unique, exposée par la collection xUnit DatabaseCollection), TestDbContext.cs et TestFirePanel.cs.

Suites d'intégration ​

SuiteCe qu'elle éprouve
EndToEndChainTestsUne table de bobines réelle lue par le vrai adaptateur, jusqu'au PanelDto tel qu'il serait poussé par SignalR — y compris les cas dégradés du transport : lecture tronquée, exception en cours de cycle, déconnexion pendant l'interrogation
SystemFlagTruthTableTestsLa table de vérité des états système. Les cas sont dérivés des définitions du profil : un état ajouté est couvert sans qu'aucun test soit écrit
ResourceChangeCoverageTestsParcourt les contrôleurs par réflexion et exige [NotifiesResource] sur toute action modifiant des données partagées
AcknowledgmentCascadeTestsLa descente d'un acquittement : synthèse → zones → points, et son absence de remontée
SecurityBoundaryTestsLes frontières d'autorisation des points d'entrée
HttpApiIntegrationTestsL'API réelle derrière WebApplicationFactory<Program>
PostgresMigrationTestsL'application des migrations sur un fournisseur relationnel
BackupResilienceTests, DatabaseBackupIntegrationTestsAller-retour export / restauration
CommandLifecycleTests, IncidentWorkflowIntegrationTestsCycle de vie d'une commande et d'un incident
CustomProfileLifecycleTests, SystemEntityEndToEndTestsProfil déclaré par l'opérateur, entités système IHM
ReportsIntegrationTestsGénération et archivage des rapports

Exécution ​

powershell
dotnet test dotnet/tests/backend/backend.tests.csproj
dotnet test dotnet/tests/backend/backend.tests.csproj -c Release                          # comme l'intégration continue
dotnet test dotnet/tests/backend/backend.tests.csproj --filter "FullyQualifiedName~FirePanelTests"

Mécanismes non évidents ​

Debug et Release ne voient pas le même backend ​

L'intégration continue compile en Release, dotnet test sans option compile en Debug. Plusieurs types du backend n'existent qu'en Debug — DemoSeedController, DemoDataSeeder, des actions de MapsController et d'AppConfigsController. Un test réflexif comme ResourceChangeCoverageTests voit donc un jeu de types différent selon la configuration, et peut passer en local tout en échouant sur l'intégration continue. Rejouer la suite en Release dès qu'un type conditionnel ou un test réflexif est touché.

L'environnement est déclaré avant le premier test ​

TestHelpers/TestEnvironment.cs pose ASPNETCORE_ENVIRONMENT=Testing depuis un [ModuleInitializer].

PointDétail
Pourquoi une variable d'environnementLe point d'entrée du backend résout ses chemins de données avant que le constructeur d'hôte n'existe ; UseEnvironment arriverait trop tard
Pourquoi un initialiseur de moduleIl s'exécute au chargement de l'assemblage, avant le premier test
Ce que cela éviteSans lui, un test qui téléverse un fichier ou démarre l'hôte écrirait dans les dossiers du service installé

Le secret applicatif de test est versionné ​

appsettings.Crypto.json est le seul fichier appsettings.Crypto.* versionné du dépôt, dé-ignoré explicitement par .gitignore. Le démarrage du backend refuse un secret absent : sans ce fichier, WebApplicationFactory<Program> ne pourrait pas construire l'hôte. Il est copié en Always pour primer sur l'artefact transitif hérité du projet backend, et la constante FireSupervisorApiFactory.SuperAdminPassword doit rester alignée sur sa valeur.

Le fournisseur InMemory n'est pas relationnel ​

Ce qu'il ne sait pas faireConséquence
ExecuteDelete et les opérations en masseLe code de production les garde derrière IsRelational()
GetDbConnection()Lève sous InMemory
Contraintes et clés étrangèresNon appliquées : un test peut passer sur un graphe qu'une vraie base refuserait

Les tests qui exigent un fournisseur relationnel passent par SQLite.

Contraintes actives ​

ContrainteConséquence si elle est ignorée
Le projet cible net9.0 sans dépendance graphiqueIl ne tournerait plus sur les agents Ubuntu de l'intégration continue
Un test va dans le dossier de la couche éprouvéeIntegration/ est réservé à ce qui traverse plusieurs couches
SQLitePCLRaw.lib.e_sqlite3 est référencé directementLa version tirée par EF Core 9.0.18 est affectée par GHSA-2m69-gcr7-jv3q ; la référence directe force la version corrigée

Documentation Technique