Tests

Structure des tests, frameworks utilises, conventions et guide d'execution des tests pour Place API.

Tests

Vue d'ensemble

Place API utilise une strategie de test a deux niveaux : tests unitaires et tests d'integration. Les tests sont executes en serie pour garantir la coherence des donnees.

Frameworks

FrameworkUsage
xUnitFramework de test principal
FluentAssertionsAssertions lisibles et expressives
NSubstituteMocking/substitution de dependances
TestcontainersPostgreSQL ephemere pour les tests d'integration
RespawnReinitialisation de la base entre les tests

Structure des projets de test

src/Modules/
├── Identity/
│   └── tests/
│       ├── UnitTest/           # Tests unitaires Identity
│       │   ├── Admin/
│       │   ├── Auth/
│       │   ├── Auditing/
│       │   ├── BackgroundJobs/
│       │   ├── Core/
│       │   ├── Infrastructure/
│       │   ├── Models/
│       │   ├── PersistMessage/
│       │   ├── Security/
│       │   ├── Services/
│       │   └── Web/
│       └── IntegrationTest/    # Tests d'integration Identity
│           ├── Admin/
│           ├── Auth/
│           ├── Auditing/
│           ├── Contracts/
│           ├── Fakes/
│           ├── Infrastructure/
│           └── Sessions/
├── Audit/
│   └── tests/
│       └── UnitTest/           # Tests unitaires Audit
│           ├── Hubs/
│           └── Services/
└── Messaging/
    └── tests/
        ├── UnitTest/           # Tests unitaires Messaging
        │   └── Infrastructure/
        └── IntegrationTest/    # Tests d'integration Messaging
            └── Infrastructure/

Tests unitaires

Couverture par module

Identity (UnitTest)

DossierFichiers de testDescription
Admin/DeactivateUserCommandHandlerTestsLogique de desactivation utilisateur
Auth/LoginCommandHandlerTests, ForgotPasswordCommandHandlerTests, ChangePasswordCommandHandlerTests, UserRegistrationServiceTests, TokenServiceTests, SocialLoginCommandHandlerTests, LinkedAccountsTests, UserSessionTests, HashedTokenTests, IpAddressValueTests, OtpCodeTests, DeviceInfoProviderTests, RequiredPermissionAuthorizationHandlerTestsLogique d'authentification et sessions
Auditing/AuditCommandBehaviorTests, AuditEmitterOutboxTests, AuditHttpMiddlewareTests, AuditMaskingServiceTests, EntityChangeAuditSaveChangesInterceptorTests, HttpAuditContextProviderTestsPipeline d'audit
BackgroundJobs/HangfireBootstrapTestsDemarrage des jobs Hangfire
Core/EventDispatcherTestsDispatch des evenements domaine
Infrastructure/RateLimitHeaderWriterTests, RateLimitPartitionKeyBuilderTests, RateLimitingOptionsValidatorTestsRate limiting
Models/PasswordHistoryTests, UserEntityTestsLogique des entites domaine
PersistMessage/OutboxDispatchRecurringJobTestsOutbox pattern
Security/InputValidationSecurityTestsValidation des entrees
Services/EmailMaskerTests, GroupRoleServiceTests, PasswordExpiryServiceTests, PermissionServiceTestsServices metier
Web/CorrelationExtensionsTests, CurrentUserServiceTests, ExceptionTests, ForwardedHeadersTrustOptionsTests, RequestContextProviderTests, ValidationErrorTestsCouche web

Audit (UnitTest)

FichierDescription
AuditHubTestsConnexion/deconnexion du hub SignalR
AuditLogWriterTestsEcriture des logs d'audit

Messaging (UnitTest)

FichierDescription
SnsSmsSenderTestsEnvoi SMS via AWS SNS

Convention de nommage

Les tests suivent la convention :

{Methode}_{Scenario}_{ResultatAttendu}

Exemples :

  • Login_WithValidCredentials_ReturnsTokens
  • Login_WithInvalidPassword_ReturnsUnauthorized
  • Register_WithExistingEmail_ReturnsConflict
  • Revoke_WithNonExistentSession_ReturnsFalse

Tests d'integration

Infrastructure

Les tests d'integration utilisent Testcontainers pour demarrer une instance PostgreSQL ephemere dans Docker. Docker doit etre en cours d'execution pour lancer les tests d'integration.

Base de test

Chaque module d'integration definit une classe de base :

  • IdentityIntegrationTestBase : Configure le WebApplicationFactory, les fakes de services, et le seeder de donnees de test.
  • MessagingIntegrationTestBase : Configuration similaire pour le module Messaging.

Reinitialisation des donnees

Respawn est utilise pour reinitialiser la base de donnees entre chaque test, garantissant l'isolation.

Couverture par module

Identity (IntegrationTest)

DossierFichiers de testDescription
Auth/LoginTests, RegisterNewUserTests, LogoutTests, RefreshTokenTests, ChangePasswordTests, ForgotPasswordTests, ResetPasswordTests, VerifyOtpTests, ResendOtpTests, SocialLoginTests, LinkedAccountsTests, LoginSecurityTestsFlux d'authentification complets
Admin/AdminUserManagementTestsGestion admin des utilisateurs
Sessions/SessionManagementTestsGestion des sessions utilisateur
Auditing/AuditAdminParityIntegrationTests, EntityChangeAuditIntegrationTests, OutboxHangfireAuditIntegrationTestsIntegration avec le module Audit
Infrastructure/ProblemDetailsIntegrationTests, RateLimitingIntegrationTests, RbacPermissionsIntegrationTests, StubServiceSecurityTests, UserModelPersistenceTestsInfrastructure transverse

Messaging (IntegrationTest)

FichierDescription
SmsSenderRegistrationTestsEnregistrement correct du service SMS

Fakes et stubs

ClasseDescription
FakeRegisterNewUserCommandCommande d'enregistrement de test
FakeSocialAuthProviderProvider d'authentification sociale factice
IdentityTestDataSeederSeeder de donnees de test

Execution des tests

Tous les tests

dotnet test

Tests par module

# Tests unitaires Identity
dotnet test src/Modules/Identity/tests/UnitTest/Unit.Test.csproj

# Tests d'integration Identity
dotnet test src/Modules/Identity/tests/IntegrationTest/Integration.Test.csproj

# Tests unitaires Audit
dotnet test src/Modules/Audit/tests/UnitTest/Audit.Unit.Test.csproj

# Tests unitaires Messaging
dotnet test src/Modules/Messaging/tests/UnitTest/Messaging.Unit.Test.csproj

# Tests d'integration Messaging
dotnet test src/Modules/Messaging/tests/IntegrationTest/Messaging.Integration.Test.csproj

Execution en CI

La CI execute les tests via Nuke :

./build.cmd Compile UnitTests IntegrationTests

Les resultats sont publies comme artefacts GitHub Actions.


Execution serielle

Les tests sont configures pour s'executer en serie (parallelizeAssembly: false) pour eviter les conflits d'acces aux donnees entre tests d'integration. Cela est configure via les fichiers xunit.runner.json ou les attributs d'assembly.


Tests d'architecture

Bien qu'il n'y ait pas encore de projet Architecture.Tests dedie, le plan de migration prevoit des tests d'architecture pour enforcer :

  • L'isolation des modules (pas de references directes entre modules internes)
  • La separation des couches (le domaine ne depend pas de l'infrastructure)
  • L'utilisation correcte des Contracts comme seul point de communication inter-modules

Exemple de test d'architecture prevu :

[Fact]
public void IdentityModule_ShouldNotReference_AuditModule_Internals()
{
    var result = Types.InAssembly(typeof(IdentityContext).Assembly)
        .ShouldNot()
        .HaveDependencyOn("Audit")
        .GetResult();
    result.IsSuccessful.Should().BeTrue();
}

Bonnes pratiques

  1. Toujours executer les tests avant de pousser (les tests d'integration requierent Docker).
  2. Utiliser la convention de nommage {Method}_{Scenario}_{ExpectedResult}.
  3. Isoler les tests -- chaque test doit etre independant grace a Respawn.
  4. Mocker les dependances externes (SMTP, SNS) dans les tests unitaires avec NSubstitute.
  5. Ne pas mocker le DbContext dans les tests d'integration -- utiliser Testcontainers.