veza/veza-backend-api/tests/integration/README.md

312 lines
7 KiB
Markdown
Raw Normal View History

2025-12-16 16:23:49 +00:00
# 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**:
```bash
# PostgreSQL
export DATABASE_URL="postgresql://veza:veza@localhost:5432/veza_test?sslmode=disable"
# Redis
export REDIS_ADDR="localhost:6379"
# RabbitMQ (optionnel)
export RABBITMQ_URL="amqp://guest:guest@localhost:5672/"
```
**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
export DATABASE_URL="postgresql://veza:veza@localhost:5432/veza_test?sslmode=disable"
export REDIS_ADDR="localhost:6379"
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 <container_id>
```
**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
---
## 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