# đŸ§Ș Guide des Tests Automatiques - Mes Budgets Participatifs ## 📋 Vue d'ensemble Ce guide dĂ©crit la suite de tests automatiques complĂšte mise en place pour l'application "Mes Budgets Participatifs". Les tests couvrent toutes les fonctionnalitĂ©s essentielles et garantissent la qualitĂ© et la fiabilitĂ© du code. ## 🎯 Objectifs des Tests ### ✅ **Couverture complĂšte** - **Services** : Logique mĂ©tier et interactions avec la base de donnĂ©es - **Composants** : Interface utilisateur et interactions - **Hooks** : Logique rĂ©utilisable et gestion d'Ă©tat - **API Routes** : Endpoints et validation des donnĂ©es - **Utilitaires** : Fonctions helper et validation - **IntĂ©gration** : Flux complets et interactions entre modules - **End-to-End** : ExpĂ©rience utilisateur complĂšte ### ✅ **QualitĂ© du code** - **FiabilitĂ©** : DĂ©tection prĂ©coce des rĂ©gressions - **MaintenabilitĂ©** : Tests comme documentation vivante - **Refactoring** : Confiance pour les modifications - **Performance** : Validation des optimisations ## đŸ—ïž Architecture des Tests ### **Structure des dossiers** ``` src/__tests__/ ├── utils/ │ └── test-utils.tsx # Utilitaires et mocks communs ├── lib/ │ ├── services.test.ts # Tests des services │ ├── auth.test.ts # Tests d'authentification │ └── utils.test.ts # Tests des utilitaires ├── components/ │ ├── AuthGuard.test.tsx # Tests du composant de protection │ └── base/ │ └── BaseModal.test.tsx # Tests des composants de base ├── hooks/ │ └── useFormState.test.ts # Tests des hooks personnalisĂ©s ├── api/ │ └── test-smtp.test.ts # Tests des API routes ├── integration/ │ └── campaign-management.test.tsx # Tests d'intĂ©gration └── e2e/ └── voting-flow.test.ts # Tests end-to-end ``` ## đŸ§Ș Types de Tests ### **1. Tests Unitaires (Jest + React Testing Library)** #### **Services (`src/__tests__/lib/`)** ```typescript // Exemple : Test du service de campagnes describe('campaignService', () => { it('should create a campaign', async () => { const result = await campaignService.create(newCampaign); expect(result).toEqual(mockCampaign); }); }); ``` **FonctionnalitĂ©s testĂ©es :** - ✅ CRUD des campagnes - ✅ Gestion des participants - ✅ Gestion des propositions - ✅ SystĂšme de vote - ✅ ParamĂštres de l'application - ✅ Gestion des erreurs #### **Composants (`src/__tests__/components/`)** ```typescript // Exemple : Test du composant AuthGuard it('should redirect when not authenticated', async () => { mockAuthService.isAuthenticated.mockResolvedValue(false); render(); await waitFor(() => { expect(mockRouter.push).toHaveBeenCalledWith('/admin/login'); }); }); ``` **FonctionnalitĂ©s testĂ©es :** - ✅ Protection des routes - ✅ Modaux et formulaires - ✅ Gestion des Ă©tats - ✅ Interactions utilisateur - ✅ Validation des props #### **Hooks (`src/__tests__/hooks/`)** ```typescript // Exemple : Test du hook useFormState it('should validate form data', () => { const { result } = renderHook(() => useFormState(initialData)); const isValid = result.current.validate(validator); expect(isValid).toBe(true); }); ``` **FonctionnalitĂ©s testĂ©es :** - ✅ Gestion d'Ă©tat des formulaires - ✅ Validation synchrone et asynchrone - ✅ Gestion des erreurs - ✅ Soumission des formulaires ### **2. Tests d'IntĂ©gration (`src/__tests__/integration/`)** #### **Gestion des Campagnes** ```typescript describe('Campaign Management Integration', () => { it('should handle complete campaign workflow', async () => { // CrĂ©er une campagne const campaign = await campaignService.create(newCampaign); // Ajouter des participants const participant = await participantService.create(newParticipant); // Ajouter des propositions const proposition = await propositionService.create(newProposition); // VĂ©rifier l'intĂ©gritĂ© des donnĂ©es expect(participant.campaign_id).toBe(campaign.id); expect(proposition.campaign_id).toBe(campaign.id); }); }); ``` **FonctionnalitĂ©s testĂ©es :** - ✅ Workflows complets - ✅ IntĂ©gritĂ© rĂ©fĂ©rentielle - ✅ Gestion des erreurs en cascade - ✅ Performance des opĂ©rations ### **3. Tests End-to-End (Playwright)** #### **Flux de Vote** ```typescript test('should complete full voting flow', async ({ page }) => { // Naviguer vers la page de vote await page.goto('/campaigns/test-campaign-id/vote/test-participant-id'); // Voter sur les propositions await page.locator('[data-testid="vote-slider"]').fill('50'); // Soumettre les votes await page.click('[data-testid="submit-votes"]'); // VĂ©rifier le succĂšs await expect(page.locator('[data-testid="success-message"]')).toBeVisible(); }); ``` **FonctionnalitĂ©s testĂ©es :** - ✅ ExpĂ©rience utilisateur complĂšte - ✅ Gestion des erreurs rĂ©seau - ✅ Mode hors ligne - ✅ Responsive design - ✅ AccessibilitĂ© ## đŸ› ïž Configuration ### **Jest Configuration (`package.json`)** ```json { "jest": { "testEnvironment": "jsdom", "setupFilesAfterEnv": ["/jest.setup.js"], "moduleNameMapping": { "^@/(.*)$": "/src/$1" }, "collectCoverageFrom": [ "src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts" ], "coverageThreshold": { "global": { "branches": 80, "functions": 80, "lines": 80, "statements": 80 } } } } ``` ### **Playwright Configuration (`playwright.config.ts`)** ```typescript export default defineConfig({ testDir: './src/__tests__/e2e', use: { baseURL: 'http://localhost:3000', trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure', }, projects: [ { name: 'chromium', use: { ...devices['Desktop Chrome'] } }, { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, { name: 'webkit', use: { ...devices['Desktop Safari'] } }, { name: 'Mobile Chrome', use: { ...devices['Pixel 5'] } }, { name: 'Mobile Safari', use: { ...devices['iPhone 12'] } }, ], }); ``` ## 🚀 Commandes de Test ### **Tests Unitaires et d'IntĂ©gration** ```bash # Lancer tous les tests npm test # Lancer les tests en mode watch npm run test:watch # Lancer les tests avec couverture npm run test:coverage # Lancer un test spĂ©cifique npm test -- --testNamePattern="campaignService" ``` ### **Tests End-to-End** ```bash # Lancer tous les tests E2E npm run test:e2e # Lancer les tests E2E en mode UI npx playwright test --ui # Lancer les tests E2E sur un navigateur spĂ©cifique npx playwright test --project=chromium # Lancer les tests E2E en mode debug npx playwright test --debug ``` ### **Tests de SĂ©curitĂ©** ```bash # Lancer les tests de sĂ©curitĂ© npm run test:security ``` ## 📊 MĂ©triques de QualitĂ© ### **Couverture de Code** - **Objectif** : 80% minimum - **Branches** : 80% - **Fonctions** : 80% - **Lignes** : 80% - **Statements** : 80% ### **Performance des Tests** - **Tests unitaires** : < 5 secondes - **Tests d'intĂ©gration** : < 30 secondes - **Tests E2E** : < 2 minutes ### **FiabilitĂ©** - **Taux de succĂšs** : > 95% - **Tests flaky** : 0 - **RĂ©gressions dĂ©tectĂ©es** : 100% ## 🔧 Mocks et Stubs ### **Mocks Supabase** ```typescript jest.mock('@/lib/supabase', () => ({ supabase: { auth: { getSession: jest.fn(), signInWithPassword: jest.fn(), signOut: jest.fn(), }, from: jest.fn(() => ({ select: jest.fn().mockReturnThis(), insert: jest.fn().mockReturnThis(), update: jest.fn().mockReturnThis(), delete: jest.fn().mockReturnThis(), eq: jest.fn().mockReturnThis(), single: jest.fn().mockReturnThis(), then: jest.fn().mockResolvedValue({ data: null, error: null }), })), }, })); ``` ### **Mocks Next.js** ```typescript jest.mock('next/navigation', () => ({ useRouter() { return { push: jest.fn(), replace: jest.fn(), prefetch: jest.fn(), back: jest.fn(), forward: jest.fn(), refresh: jest.fn(), }; }, useSearchParams() { return new URLSearchParams(); }, usePathname() { return '/'; }, })); ``` ## 🎯 Bonnes Pratiques ### **Nommage des Tests** ```typescript // ✅ Bon : Description claire et spĂ©cifique it('should create campaign with valid data', async () => { // Test implementation }); // ❌ Mauvais : Description vague it('should work', async () => { // Test implementation }); ``` ### **Organisation des Tests** ```typescript describe('CampaignService', () => { describe('create', () => { it('should create campaign with valid data', async () => { // Test implementation }); it('should reject invalid data', async () => { // Test implementation }); }); describe('update', () => { it('should update existing campaign', async () => { // Test implementation }); }); }); ``` ### **Gestion des DonnĂ©es de Test** ```typescript // ✅ Bon : DonnĂ©es de test centralisĂ©es export const mockCampaign = { id: 'test-campaign-id', title: 'Test Campaign', description: 'Test description', status: 'deposit' as const, budget_per_user: 100, spending_tiers: '10,25,50,100', slug: 'test-campaign', created_at: '2024-01-01T00:00:00Z', updated_at: '2024-01-01T00:00:00Z', }; ``` ## 🚹 Gestion des Erreurs ### **Tests d'Erreur** ```typescript it('should handle network errors gracefully', async () => { mockCampaignService.getAll.mockRejectedValue(new Error('Network error')); await expect(campaignService.getAll()).rejects.toThrow('Network error'); }); ``` ### **Tests de Validation** ```typescript it('should validate required fields', async () => { const invalidData = { title: '', description: '' }; const result = validateCampaignData(invalidData); expect(result.errors.title).toBe('Title is required'); expect(result.errors.description).toBe('Description is required'); }); ``` ## 📈 IntĂ©gration Continue ### **GitHub Actions** ```yaml name: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 - run: npm ci - run: npm test - run: npm run test:coverage - run: npm run test:e2e ``` ### **Seuils de QualitĂ©** - **Couverture** : 80% minimum - **Tests E2E** : 100% de succĂšs - **Linting** : 0 erreurs - **Build** : SuccĂšs obligatoire ## 🔍 Debugging des Tests ### **Tests Unitaires** ```bash # Debug avec console.log npm test -- --verbose # Debug avec debugger npm test -- --runInBand --no-cache ``` ### **Tests E2E** ```bash # Mode debug interactif npx playwright test --debug # Mode UI pour inspection npx playwright test --ui # Screenshots et vidĂ©os npx playwright test --reporter=html ``` ## 📚 Ressources ### **Documentation Officielle** - [Jest Documentation](https://jestjs.io/docs/getting-started) - [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) - [Playwright Documentation](https://playwright.dev/docs/intro) ### **Exemples de Code** - [Tests des Services](./src/__tests__/lib/services.test.ts) - [Tests des Composants](./src/__tests__/components/AuthGuard.test.tsx) - [Tests E2E](./src/__tests__/e2e/voting-flow.test.ts) --- **Cette suite de tests garantit la qualitĂ©, la fiabilitĂ© et la maintenabilitĂ© de l'application "Mes Budgets Participatifs" ! 🚀**