Tests d’intégration

Chaque projet généré à partir des modèles comprend un <YourProject>.Tests.Integration projet, câblé et prêt à être exécuté. Ses tests vont sur un environnement Dataverse réel plutôt que sur des simulations, car la plupart des failles d’un portail résident dans les joints qu’un mock remplace — traduction de requêtes, métadonnées, formatage, permissions. Deux classes de base sont fournies, une pour chaque côté de celle-ci.

Qu’y a-t-il dans le projet

Le modèle envoie ces fichiers ; ils sont des sources ordinaires dans votre dépôt, donc changez-les librement.

Fichier Objectif
PortalEndpointTestBase.cs Démarre votre portail en mémoire et expose un HttpClient contre. On dérive de cela pour les tests de terminaison et de permissions.
TestBase.cs Construit un conteneur de services avec une connexion Dataverse authentifiée. Dérivez de cela pour appeler directement vos propres services et logique.
TestAuthentication.cs Le schéma d’authentification de test et le TestUserContext qui décide sous qui une requête s’exécute.
appsettings.json, xunit.runner.json Paramètres non secrets, et la configuration xunit runner qui maintient les collections en série.
ExampleTests.cs, README.md Des exemples fonctionnels des deux bases (j’ai sauté jusqu’à ce qu’on les pointe vers de vrais documents), et une courte référence locale.

Choisir une base

Les deux sont complémentaires — ils testent différentes couches, et une suite saine utilise les deux.

Configuration et secrets

Pointez D365:Url l’environnement contre lequel les tests doivent fonctionner — appsettings.json un environnement de développement ou jetable, puisque les tests créent et suppriment des enregistrements. Les identifiants proviennent de secrets utilisateur, et le projet de test déclare délibérément la même UserSecretsId chose que le projet web, donc un portail qui fonctionne déjà localement n’a pas besoin de plus. Pour les définir explicitement :

Les sources sont superposées appsettings.json → secrets utilisateur → variables d’environnement, donc un agent de compilation peut tout fournir via des variables d’environnement (D365__ClientSecret, en utilisant le double soulignement) sans toucher à un fichier. Ne jamais mettre le secret client dans appsettings.json, qui est validé.

Note

Vous n’avez pas besoin d’une clé de licence pour effectuer des tests. L’hôte en mémoire écoute sur une adresse loopback, et loopback est licencié sans une — pas d’enregistrement Portal Website et pas de double test requis.

Test des terminaux et des permissions

Dériver de PortalEndpointTestBase et effectuer des requêtes avec Client. Les requêtes commencent anonymes, ce qui est la règle par défaut pour affirmer qu’un point de terminaison repousse les appelants anonymes. Les redirections ne sont pas suivies, donc un test peut s’affirmer sur un 302 plutôt que sur la page sur laquelle il atterrirait.

Agir en tant qu’utilisateur

SignInAs est celui qu’il faut atteindre. Il ne stub que l’étape de la certification — le principal qu’il émet porte les mêmes revendications qu’une vraie connexion, donc l’autorisation, les gestionnaires de permissions et toutes les extensions de lecture de revendications se comportent comme en production. Pas de mot de passe, pas de provisionnement, et il peut changer d’identité entre les requêtes dans un seul test.

LoginAsync publie les véritables identifiants sur le point de connexion et conserve le cookie, pour quand le chemin de connexion lui-même est en cours de test. Il faut un contact avec un mot de passe et un email confirmé, donc c’est plus lent ; les deux coexistent et la base revient au vrai cookie dès qu’aucun utilisateur usurpé n’est défini.

Note

LoginAsync a besoin des terminaux d’authentification JSON, qui sont mappés pour les hôtes React et Blazor WebAssembly/Auto. Un projet Blazor affiché par serveur se connecte via des messages de formulaire sur les pages du compte Razor, donc /api/auth/login n’est pas mappé là et LoginAsync renvoie 404 — utilisez SignInAs, qui fonctionne dans tous les hôtes.

Mise en place, démontage et remplacements

Trois crochets couvrent les besoins habituels. ConfigureTestServices S’exécute après les propres enregistrements de votre application, donc un Replace là l’emporte Program.cs — la manière de faire un faux pour une dépendance sortante. OnInitializedAsync Et OnDisposingAsync mettez chaque test entre crochets pour le seeding et le cleanup, et le démontage s’exécute même en cas d’échec du test.

Important

Ces tests lancent votre portail, donc tout ce qui l’empêche de démarrer les arrête aussi. En particulier, avec l’autorisation améliorée activée, l’hébergeur valide l’identifiant du site web configuré au démarrage et échoue avec des instructions jusqu’à ce qu’un identifiant réel powerpagesite soit fourni — la même condition préalable que pour l’exécution du portail.

Services de test et logique

Dérivez de TestBase, enregistrez ce dont le code testé a besoin, et résolvez-le. Le client Dataverse est déjà authentifié.

Passez un identifiant utilisateur à CreateOrganizationService(userId) pour l’usurper — Dataverse applique alors les privilèges propres à cet utilisateur, ce qui permet de vérifier l’accès au niveau des enregistrements depuis le côté données plutôt que via un point de terminaison.

CreateWebApiHttpClientAsync() renvoie un client authentifié par rapport à l’API Web Dataverse (/api/data/v9.2/) pour des assertions plus faciles à exprimer dans OData que via le SDK. Il nécessite Azure:TenantId à la fois la configuration ainsi que l’identifiant client et le secret.

Comment se déroulent les tests

Exécutez-les avec dotnet test, ou depuis l’explorateur de test de votre IDE. Quelques caractéristiques valent la peine d’être connues avant d’en écrire beaucoup :

Meilleures pratiques

Pointez la suite vers un environnement de développement, jamais vers la production. Ce sont de vraies écritures sur de vraies données, et un test qui supprime ce qu’il a créé supprimera l’enregistrement réel si vous le visez vers un.