# Tests d'Intégration - veza-backend-api **Objectif**: Tests d'intégration reproductibles validant le comportement réel du système avec dépendances externes. --- ## Contrat d'Environnement Minimal ### Services Requis Les tests d'intégration nécessitent les services suivants: 1. **PostgreSQL** (obligatoire) - Version: 15+ - Base de données: `veza_test` - Utilisateur: `veza` / Mot de passe: `veza` - Migrations: Appliquées automatiquement via testcontainers 2. **Redis** (obligatoire pour certains tests) - Version: 7+ - Port: 6379 (par défaut) - Aucune base de données spécifique requise 3. **RabbitMQ** (optionnel) - Utilisé uniquement pour tests spécifiques - Peut être skippé si non disponible ### Méthodes de Setup #### Option 1: Testcontainers (Recommandé) **Avantages**: - ✅ Reproductible (même environnement partout) - ✅ Isolation complète (pas de pollution entre tests) - ✅ Pas de configuration manuelle requise - ✅ Fonctionne en CI/CD **Prérequis**: - Docker installé et en cours d'exécution - Go 1.21+ **Utilisation**: ```bash # Les tests utilisent automatiquement testcontainers go test ./tests/integration/... -tags integration -v ``` **Configuration**: - PostgreSQL: Démarre automatiquement via `internal/testutils/setup.go` - Redis: Démarre automatiquement via `internal/testutils/setup_redis.go` (à créer) - Migrations: Appliquées automatiquement depuis `migrations/` #### Option 2: Services Locaux (Alternative) **Quand utiliser**: - Docker non disponible - Tests de développement rapide - Debugging local **Configuration** (choisir selon la stack démarrée): * Avec `make infra-up` (docker-compose.yml dev) : ```bash export DATABASE_URL="postgresql://veza:password@localhost:15432/veza?sslmode=disable" export REDIS_ADDR="localhost:16379" export REDIS_TEST_URL="redis://localhost:16379/15" export RABBITMQ_URL="amqp://veza:password@localhost:15672/" ``` * Avec `docker-compose.test.yml` (stack dédiée tests) : ```bash export DATABASE_URL="postgresql://veza_test:veza_test@localhost:5434/veza_test?sslmode=disable" export REDIS_ADDR="localhost:6380" export REDIS_TEST_URL="redis://localhost:6380/15" export RABBITMQ_URL="amqp://veza_test:veza_test@localhost:5673/" ``` **Setup manuel**: ```bash # PostgreSQL createdb veza_test psql veza_test < migrations/*.sql # Redis redis-server # RabbitMQ (optionnel) docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management ``` --- ## Exécution des Tests ### Tests d'Intégration (Tous) ```bash # Avec testcontainers (recommandé) go test ./tests/integration/... -tags integration -v # Avec services locaux (ports selon make infra-up) export DATABASE_URL="postgresql://veza:password@localhost:15432/veza?sslmode=disable" export REDIS_ADDR="localhost:16379" go test ./tests/integration/... -tags integration -v ``` ### Tests Spécifiques ```bash # Test upload async polling go test ./tests/integration -tags integration -run TestUploadAsyncPollingStatus -v # Test upload scalability go test ./tests/integration -tags integration -run TestUploadScalability -v ``` ### Via Makefile ```bash # Tous les tests d'intégration make test-integration # Tests avec quarantaine (validation manuelle) make test-quarantine ``` --- ## Structure des Tests ### Tests Non-Quarantinés Ces tests doivent **toujours passer** avant production: - `TestUploadAsyncPollingStatus` - Upload async avec polling status - `TestUploadScalability` - Upload distribué avec Redis ### Tests Quarantinés Voir `QUARANTINE.md` pour la classification complète. **Classification**: - 🔴 **Doit passer avant prod** - Bloquant pour release - 🟡 **CI nightly** - Exécuté en CI séparé, non-bloquant - 🟢 **Manual only** - Exécution manuelle uniquement --- ## Dépannage ### Erreur: "Docker not running" **Solution**: Démarrer Docker ```bash # Linux sudo systemctl start docker # macOS open -a Docker ``` ### Erreur: "PostgreSQL container failed to start" **Solution**: Vérifier logs testcontainers ```bash docker ps -a | grep postgres docker logs ``` **Cause commune**: Port 5432 déjà utilisé ```bash # Vérifier processus utilisant le port lsof -i :5432 # Arrêter processus ou changer port dans test ``` ### Erreur: "Redis not available" **Solution 1**: Utiliser testcontainers (recommandé) - Les tests utilisent automatiquement testcontainers si disponible **Solution 2**: Démarrer Redis localement ```bash redis-server # ou docker run -d -p 6379:6379 redis:7-alpine ``` ### Test Flaky (intermittent) **Actions**: 1. Vérifier logs testcontainers pour timeouts 2. Augmenter timeouts dans setup si nécessaire 3. Vérifier ressources système (CPU, mémoire) 4. Documenter dans `QUARANTINE.md` si non-résolvable ### Tests internal/testutils et SetupTestDB() Les tests dans `internal/testutils` qui utilisent `SetupTestDB()` (db_cleanup_test, db_test, fixtures_test) nécessitent Docker et testcontainers (PostgreSQL). En l'absence de Docker ou avec `-short`: - Ces tests sont automatiquement skippés via `SkipIfDockerUnavailable(t)` - Pour exécuter tous les tests sans Docker: `go test ./... -short` (les tests testutils seront skippés) - Pour exécuter les tests testutils: s'assurer que Docker est démarré et ne pas utiliser `-short` --- ## Variables d'Environnement ### Pour Tests avec Services Locaux | Variable | Description | Défaut | |----------|-------------|--------| | `DATABASE_URL` | PostgreSQL connection string | `postgresql://veza:veza@localhost:5432/veza_test?sslmode=disable` | | `REDIS_ADDR` | Redis address | `localhost:6379` | | `RABBITMQ_URL` | RabbitMQ connection string | `amqp://guest:guest@localhost:5672/` | | `SKIP_TESTCONTAINERS` | Forcer services locaux (si `true`) | `false` | ### Pour Tests avec Testcontainers Aucune variable requise - testcontainers démarre automatiquement les services. --- ## CI/CD ### Pipeline Normal ```yaml - name: Run unit tests run: go test ./internal/... -short -tags '!integration' ``` ### Pipeline Intégration (Séparé) ```yaml - name: Run integration tests run: go test ./tests/integration/... -tags integration -v services: docker: image: docker:latest ``` **Note**: Les tests d'intégration peuvent être exécutés: - En CI nightly (tous les tests) - En CI sur demande (workflow_dispatch) - En CI sur PR (tests non-quarantinés uniquement) --- ## Bonnes Pratiques ### 1. Isolation des Tests - ✅ Chaque test utilise sa propre base de données (via testcontainers) - ✅ Nettoyage automatique après chaque test - ✅ Pas de dépendances entre tests ### 2. Reproductibilité - ✅ Utiliser testcontainers pour environnement identique - ✅ Éviter les timeouts courts (< 1s) - ✅ Éviter les sleeps fixes (utiliser polling avec timeout) ### 3. Performance - ✅ Tests parallèles quand possible (`t.Parallel()`) - ✅ Timeouts raisonnables (5-10s max par test) - ✅ Nettoyer ressources (containers, fichiers) après test ### 4. Fiabilité - ✅ Tests non-flaky (passent 100% du temps) - ✅ Messages d'erreur clairs - ✅ Skip si dépendances manquantes (avec message) --- ## Exemples ### Exemple 1: Test avec Testcontainers ```go func TestMyIntegration(t *testing.T) { ctx := context.Background() // PostgreSQL via testcontainers dsn, err := testutils.GetTestContainerDB(ctx) require.NoError(t, err) db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) require.NoError(t, err) // Test... } ``` ### Exemple 2: Test avec Services Locaux ```go func TestMyIntegration(t *testing.T) { dsn := os.Getenv("DATABASE_URL") if dsn == "" { t.Skip("DATABASE_URL not set, skipping integration test") } db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) require.NoError(t, err) // Test... } ``` --- ## Références - Testcontainers Go: https://golang.testcontainers.org/ - Quarantaine: `tests/integration/QUARANTINE.md` - Setup helpers: `internal/testutils/setup.go` --- **Dernière mise à jour**: 2025-12-15 **Maintenu par**: Veza Backend Team