Le reporting de tests en CI couvre trois préoccupations. Stocker les artefacts (rapports HTML, traces, captures d'écran) pour que les échecs soient inspectables après l'exécution. Publier les résultats dans un format compris par le tableau de bord CI (JUnit XML). Remonter les échecs là où les développeurs regardent vraiment (commentaires de PR).

Le problème avec la sortie brute des tests

La sortie CI par défaut pour une exécution Playwright en échec ressemble à ceci :

  ✘ tests/login.spec.ts > shows error for wrong password (15234ms)
    Error: Timed out 5000ms waiting for expect(locator).toBeVisible()

    Call log:
      - expect.toBeVisible with timeout 5000ms
      - waiting for locator('[data-testid="error-message"]')

Vous devez parcourir des centaines de lignes de sortie pour trouver les échecs. Dans une suite de 200 tests, c'est pénible.

Formats de rapport

JUnit XML

Le format universel : chaque système CI le comprend.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="Login Tests" tests="5" failures="1" time="12.5">
    <testcase name="shows error for wrong password" time="15.2">
      <failure message="Timed out waiting for error-message">
        Error: Timed out 5000ms waiting for expect(locator).toBeVisible()
        ...
      </failure>
    </testcase>
    <testcase name="successful login redirects to dashboard" time="3.2" />
  </testsuite>
</testsuites>

Générer depuis Playwright :

// playwright.config.ts
reporter: [
  ['junit', { outputFile: 'test-results/results.xml' }],
  ['list'],  // Afficher aussi la sortie dans la console
],

Rapport HTML

Le rapport HTML intégré de Playwright, visuel, avec captures d'écran et traces.

reporter: [
  ['html', { outputFolder: 'playwright-report', open: 'never' }],
],

Générer et ouvrir en local :

npx playwright show-report

JSON

Format lisible par machine pour un traitement personnalisé :

reporter: [
  ['json', { outputFile: 'test-results/results.json' }],
],

Utile pour construire des tableaux de bord personnalisés ou analyser les résultats par programme.

Reporters multiples

Vous voulez généralement plusieurs formats :

reporter: process.env.CI
  ? [
      ['junit', { outputFile: 'test-results/results.xml' }],
      ['html', { outputFolder: 'playwright-report', open: 'never' }],
      ['list'],  // Sortie en temps réel dans les logs CI
    ]
  : [
      ['html'],  // En local : juste le rapport visuel
      ['list'],
    ],

Intégration GitHub Actions

Configuration de base avec upload d'artefact

name: Playwright 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
          cache: npm

      - run: npm ci
      - run: npx playwright install --with-deps chromium

      - name: Run tests
        run: npx playwright test
        env:
          BASE_URL: ${{ secrets.STAGING_URL }}

      # Toujours uploader le rapport, même quand les tests échouent
      - name: Upload HTML report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

      - name: Upload JUnit results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-results
          path: test-results/results.xml

Le if: always() est critique : sans lui, l'étape d'upload est ignorée quand les tests échouent.

Annotations de tests JUnit dans GitHub

GitHub Actions peut analyser le XML JUnit et annoter votre PR avec les échecs directement dans le diff :

- name: Report test results
  uses: dorny/test-reporter@v1
  if: always()
  with:
    name: Playwright Tests
    path: test-results/results.xml
    reporter: java-junit
    fail-on-error: true

Cela affiche un résumé dans l'interface PR de GitHub et annote les tests en échec dans le code.

Intégration GitLab CI

GitLab a un support natif JUnit :

test:
  image: mcr.microsoft.com/playwright:v1.44.0-jammy
  script:
    - npm ci
    - npx playwright test
  artifacts:
    when: always
    reports:
      junit: test-results/results.xml  # Support JUnit natif
    paths:
      - playwright-report/             # Uploader aussi le rapport HTML
    expire_in: 1 week

GitLab lit le XML JUnit et affiche un résumé de tests dans l'interface de pipeline, sans outils supplémentaires.

Notifications Slack

Envoyer des résumés d'échecs à Slack quand les tests CI échouent :

- name: Notify Slack on failure
  if: failure()
  uses: slackapi/slack-github-action@v1
  with:
    payload: |
      {
        "text": "❌ Playwright tests failed on ${{ github.ref_name }}",
        "attachments": [{
          "color": "danger",
          "fields": [
            {
              "title": "Branch",
              "value": "${{ github.ref_name }}",
              "short": true
            },
            {
              "title": "Run",
              "value": "${{ github.run_id }}",
              "short": true
            },
            {
              "title": "Report",
              "value": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            }
          ]
        }]
      }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Analyser les résultats par programme

Parfois vous avez besoin d'une logique personnalisée : notifier uniquement sur les nouveaux échecs, pas les ré-échecs.

// scripts/parse-results.js
const fs = require('fs');
const xml2js = require('xml2js');

async function parseResults() {
  const xml = fs.readFileSync('test-results/results.xml', 'utf8');
  const result = await xml2js.parseStringPromise(xml);

  const testsuites = result.testsuites.testsuite;
  const failures = [];

  testsuites.forEach(suite => {
    (suite.testcase || []).forEach(testcase => {
      if (testcase.failure) {
        failures.push({
          name: testcase.$.name,
          suite: suite.$.name,
          message: testcase.failure[0].$.message,
          time: testcase.$.time,
        });
      }
    });
  });

  console.log(`Total failures: ${failures.length}`);
  failures.forEach(f => {
    console.log(`- [${f.suite}] ${f.name}`);
    console.log(`  ${f.message}`);
  });

  process.exit(failures.length > 0 ? 1 : 0);
}

parseResults();

Commentaire résumé des tests sur les PRs

Commenter automatiquement un résumé de tests sur chaque PR :

- name: Test summary comment
  uses: marocchino/sticky-pull-request-comment@v2
  if: always()
  with:
    header: test-results
    message: |
      ## Test Results

      ${{ steps.test-results.outputs.summary }}

      [View full report](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})

Rétention et historique

Les résultats bruts ne sont utiles que si vous les conservez assez longtemps.

GitHub Actions :

- uses: actions/upload-artifact@v4
  with:
    retention-days: 30  # Conserver 30 jours

Pour un historique plus long : Allure TestOps (payant) conserve un historique illimité. Un bucket S3/GCS auto-hébergé permet de stocker results.json et de générer des rapports de tendance. Datadog ou Grafana acceptent des métriques depuis les exécutions de tests pour alimenter des tableaux de bord.

Ce qu'il faut mettre dans chaque rapport CI

Un rapport de tests utile répond à :

1. Combien de tests ont réussi / échoué / été ignorés ? Comptages résumés

2. Quels tests ont échoué ? Liste complète des échecs avec les noms des tests

3. Pourquoi ont-ils échoué ? Messages d'erreur et stack traces

4. À quoi ça ressemble ? Captures d'écran pour les tests UI

5. Combien de temps ça a pris ? Temps d'exécution par test

6. Est-ce un nouvel échec ? Comparaison avec l'exécution précédente

Le rapport HTML de Playwright couvre les points 1 à 5. Les outils de tendance (Allure, TestOps) ajoutent le 6.

Résumé

| Format | Idéal pour |

|---|---|

| JUnit XML | Intégration avec le système CI, annotations de PR |

| HTML | Lecture humaine, captures d'écran, traces |

| JSON | Traitement personnalisé, tableaux de bord |

| List | Sortie console en temps réel |

Configuration minimale pour la CI :

1. Générer le XML JUnit (la CI peut le lire)

2. Uploader le rapport HTML comme artefact

3. Utiliser if: always() sur les étapes d'upload

Configuration améliorée :
  • Rapport Allure avec tendances
  • Notification Slack en cas d'échec
  • Commentaire de PR avec résumé
  • Annotation de test dans la vue diff
→ See also: Rapports Allure pour Playwright: Configuration de Rapports de Tests Enrichis | Rapports de Tests Playwright: HTML Intégré vs Allure | CI/CD pour QA: GitHub Actions, Jenkins et GitLab Comparés