Guide de test des dramaturges : tests E2E pour les applications Next.js

Écrivez des tests de bout en bout fiables pour les applications Next.js avec Playwright. Guide complet couvrant la configuration, les objets de page, les tests d'authentification, la régression visuelle et l'intégration CI/CD.

E

ECOSIRE Research and Development Team

Équipe ECOSIRE

5 mars 20266 min de lecture1.3k Mots

Guide de test des dramaturges : tests E2E pour les applications Next.js

Les tests de bout en bout détectent les bugs manqués par les tests unitaires : flux d'authentification interrompus, échecs de soumission de formulaires, erreurs de navigation et problèmes de rendu entre navigateurs. Playwright, construit par Microsoft, est devenu le principal framework de tests E2E grâce à sa prise en charge multi-navigateurs, ses capacités d'attente automatique et ses puissants outils de débogage.

Points clés à retenir

  • Les tests Playwright sont exécutés sur Chromium, Firefox et WebKit à partir d'une seule suite de tests
  • L'attente automatique élimine les tests irréguliers en attendant que les éléments soient exploitables avant d'interagir
  • L'état d'authentification peut être partagé entre les tests pour une exécution plus rapide
  • L'intégration de CI avec GitHub Actions permet des tests automatisés sur chaque demande d'extraction

Configuration du projet

###Installation

npm init playwright@latest

Cela installe Playwright, crée un fichier de configuration et télécharge les binaires du navigateur. Pour les projets Next.js, configurez le serveur Web pour qu'il démarre automatiquement :

// playwright.config.ts
import { defineConfig } from "@playwright/test";

export default defineConfig({
  testDir: "./e2e",
  timeout: 30000,
  retries: process.env.CI ? 2 : 0,
  use: {
    baseURL: "http://localhost:3000",
    screenshot: "only-on-failure",
    trace: "on-first-retry",
  },
  webServer: {
    command: "npm run dev",
    port: 3000,
    reuseExistingServer: !process.env.CI,
  },
  projects: [
    { name: "chromium", use: { browserName: "chromium" } },
    { name: "firefox", use: { browserName: "firefox" } },
    { name: "webkit", use: { browserName: "webkit" } },
  ],
});

Rédiger votre premier test

Test de navigation de base

// e2e/navigation.spec.ts
import { test, expect } from "@playwright/test";

test("home page loads and displays title", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/ECOSIRE/);
  await expect(page.getByRole("heading", { level: 1 })).toBeVisible();
});

test("navigation to services page", async ({ page }) => {
  await page.goto("/");
  await page.getByRole("link", { name: "Services" }).click();
  await expect(page).toHaveURL(/services/);
  await expect(page.getByRole("heading", { name: /Services/ })).toBeVisible();
});

Test de soumission de formulaire

test("contact form submission", async ({ page }) => {
  await page.goto("/contact");

  await page.getByLabel("Name").fill("Test User");
  await page.getByLabel("Email").fill("[email protected]");
  await page.getByLabel("Message").fill("This is a test message");
  await page.getByRole("button", { name: "Send" }).click();

  await expect(page.getByText("Message sent")).toBeVisible();
});

Modèle d'objet de page

Encapsulez les interactions de page dans des objets de page pour des raisons de maintenabilité :

// e2e/pages/login.page.ts
import { Page, expect } from "@playwright/test";

export class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto("/login");
  }

  async login(email: string, password: string) {
    await this.page.getByLabel("Email").fill(email);
    await this.page.getByLabel("Password").fill(password);
    await this.page.getByRole("button", { name: "Sign In" }).click();
  }

  async expectLoggedIn() {
    await expect(this.page).toHaveURL(/dashboard/);
  }

  async expectError(message: string) {
    await expect(this.page.getByText(message)).toBeVisible();
  }
}

Utilisation dans les tests :

test("successful login", async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.goto();
  await loginPage.login("[email protected]", "password123");
  await loginPage.expectLoggedIn();
});

Test d'authentification

État d'authentification partagé

Évitez de vous connecter avant chaque test en enregistrant l'état d'authentification :

// e2e/auth.setup.ts
import { test as setup } from "@playwright/test";

setup("authenticate", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("Email").fill("[email protected]");
  await page.getByLabel("Password").fill("admin-password");
  await page.getByRole("button", { name: "Sign In" }).click();
  await page.waitForURL("/dashboard");

  // Save authentication state
  await page.context().storageState({ path: ".auth/user.json" });
});

Configurez dans playwright.config.ts :

projects: [
  { name: "setup", testMatch: /auth\.setup\.ts/ },
  {
    name: "authenticated",
    dependencies: ["setup"],
    use: { storageState: ".auth/user.json" },
  },
],

Tests de régression visuelle

Détectez les changements visuels involontaires grâce aux comparaisons de captures d'écran :

test("home page visual regression", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveScreenshot("home-page.png", {
    maxDiffPixelRatio: 0.01,
  });
});

Lors de la première exécution, Playwright enregistre les captures d'écran de base. Les exécutions suivantes sont comparées aux références et échouent si les différences dépassent le seuil. Mettez à jour les lignes de base avec --update-snapshots lorsque les modifications sont intentionnelles.


API moqueuse

Réponses d'API simulées pour les tests déterministes :

test("displays products from API", async ({ page }) => {
  await page.route("/api/products", async (route) => {
    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify([
        { id: 1, name: "Product A", price: 29.99 },
        { id: 2, name: "Product B", price: 49.99 },
      ]),
    });
  });

  await page.goto("/products");
  await expect(page.getByText("Product A")).toBeVisible();
  await expect(page.getByText("Product B")).toBeVisible();
});

Intégration CI/CD

Actions GitHub

name: E2E Tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

Les rapports de test ayant échoué sont téléchargés sous forme d'artefacts pour le débogage, notamment des captures d'écran, des traces et des enregistrements vidéo.


Outils de débogage

  • Playwright Inspector : exécutez des tests avec l'indicateur --debug pour une exécution étape par étape
  • Trace Viewer : ouvrez les traces pour voir chaque action, requête réseau et instantané DOM
  • Codegen : exécutez npx playwright codegen pour enregistrer les interactions du navigateur et générer du code de test
  • VS Code Extension : exécutez et déboguez des tests directement à partir de VS Code avec des éléments cliquables pour localiser

## meilleures pratiques

  1. Utilisez des sélecteurs basés sur les rôles : préférez getByRole, getByLabel, getByText aux sélecteurs CSS
  2. Évitez les attentes codées en dur : faites confiance à l'attente automatique au lieu de page.waitForTimeout()
  3. Isoler les tests : chaque test doit être indépendant et ne pas dépendre d'autres tests
  4. Testez les flux d'utilisateurs, pas la mise en œuvre : concentrez-vous sur ce que font les utilisateurs, pas sur le fonctionnement du code
  5. Gardez les tests rapides : utilisez les raccourcis API pour la configuration (créez des données de test via l'API, pas l'interface utilisateur)
  6. Exécuter en CI : chaque demande d'extraction doit réussir les tests E2E avant la fusion

Questions fréquemment posées

Q : Comment Playwright se compare-t-il à Cypress ?

Playwright prend en charge plusieurs navigateurs (Chromium, Firefox, WebKit) de manière native, tandis que Cypress cible principalement Chromium. Playwright est plus rapide pour l’exécution parallèle et gère plusieurs onglets/fenêtres. Cypress a une courbe d'apprentissage légèrement plus facile et un débogage de voyage dans le temps plus fort.

Q : Comment gérons-nous les tests irréguliers ?

L’attente automatique du dramaturge élimine la plupart des défauts. Pour les problèmes restants : utilisez d'abord les assertions Web (localisateur d'attente), évitez de tester le comportement dépendant du timing et configurez les tentatives dans CI. Les rapports de trace aident à identifier la cause première des pannes intermittentes.

Q : Devons-nous tester chaque page ?

Concentrez-vous sur les flux d'utilisateurs critiques : authentification, flux de travail de base, soumissions de formulaires et flux de paiement. Toutes les pages ne nécessitent pas de tests E2E : utilisez des tests unitaires et d'intégration pour une couverture au niveau des composants.

Q : Combien de temps les tests E2E devraient-ils prendre ?

Les tests individuels devraient se terminer en moins de 30 secondes. Une suite complète pour une application de taille moyenne (50 à 100 tests) devrait s'exécuter en moins de 10 minutes avec une exécution parallèle.


Quelle est la prochaine étape

Les tests E2E avec Playwright garantissent que votre application fonctionne correctement du point de vue de l'utilisateur. Commencez par les flux critiques et étendez la couverture à mesure que votre application se développe.

Contactez ECOSIRE pour obtenir de l'aide sur l'automatisation des tests, ou explorez nos services de mise en œuvre Odoo pour un déploiement ERP de qualité garantie.


Publié par ECOSIRE – aider les entreprises à évoluer grâce à des solutions logicielles d'entreprise.

E

Rédigé par

ECOSIRE Research and Development Team

Création de produits numériques de niveau entreprise chez ECOSIRE. Partage d'analyses sur les intégrations Odoo, l'automatisation e-commerce et les solutions d'entreprise propulsées par l'IA.

Discutez sur WhatsApp