Skip to content

Le runner de tests de Bun prend désormais en charge le reporting de couverture de code intégré. Cela facilite la visualisation de la quantité de codebase couverte par les tests et la recherche des zones qui ne sont pas actuellement bien testées.

Activer la couverture

bun:test prend en charge la visualisation des lignes de code couvertes par les tests. Pour utiliser cette fonctionnalité, passez --coverage à la CLI. Cela affichera un rapport de couverture dans la console :

bash
bun test --coverage

-------------|---------|---------|-------------------
File         | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files    |   38.89 |   42.11 |
 index-0.ts  |   33.33 |   36.84 | 10-15,19-24
 index-1.ts  |   33.33 |   36.84 | 10-15,19-24
 index-10.ts |   33.33 |   36.84 | 10-15,19-24
 index-2.ts  |   33.33 |   36.84 | 10-15,19-24
 index-3.ts  |   33.33 |   36.84 | 10-15,19-24
 index-4.ts  |   33.33 |   36.84 | 10-15,19-24
 index-5.ts  |   33.33 |   36.84 | 10-15,19-24
 index-6.ts  |   33.33 |   36.84 | 10-15,19-24
 index-7.ts  |   33.33 |   36.84 | 10-15,19-24
 index-8.ts  |   33.33 |   36.84 | 10-15,19-24
 index-9.ts  |   33.33 |   36.84 | 10-15,19-24
 index.ts    |  100.00 |  100.00 |
-------------|---------|---------|-------------------

Activer par défaut

Pour toujours activer le reporting de couverture par défaut, ajoutez la ligne suivante à votre bunfig.toml :

toml
[test]
# Toujours activer la couverture
coverage = true

Par défaut, les rapports de couverture incluront les fichiers de test et excluront les sourcemaps. C'est généralement ce que vous voulez, mais cela peut être configuré autrement dans bunfig.toml.

toml
[test]
coverageSkipTestFiles = true  # par défaut false

Seuils de couverture

Il est possible de spécifier un seuil de couverture dans bunfig.toml. Si votre suite de tests n'atteint pas ou ne dépasse pas ce seuil, bun test se terminera avec un code de sortie non nul pour indiquer l'échec.

Seuil simple

toml
[test]
# Pour exiger 90% de couverture au niveau des lignes et des fonctions
coverageThreshold = 0.9

Seuils détaillés

toml
[test]
# Pour définir différents seuils pour les lignes et les fonctions
coverageThreshold = { lines = 0.9, functions = 0.9, statements = 0.9 }

La définition de l'un de ces seuils active fail_on_low_coverage, ce qui fait échouer l'exécution des tests si la couverture est inférieure au seuil.

Reporters de couverture

Par défaut, les rapports de couverture sont affichés dans la console.

Pour des rapports de couverture persistants dans les environnements CI et pour d'autres outils, vous pouvez passer une option CLI --coverage-reporter=lcov ou l'option coverageReporter dans bunfig.toml.

toml
[test]
coverageReporter = ["text", "lcov"]  # par défaut ["text"]
coverageDir = "path/to/somewhere"    # par défaut "coverage"

Reporters disponibles

ReporterDescription
textAffiche un résumé textuel de la couverture dans la console
lcovEnregistre la couverture au format lcov

Reporter de couverture LCOV

Pour générer un rapport lcov, vous pouvez utiliser le reporter lcov. Cela générera un fichier lcov.info dans le répertoire de couverture.

toml
[test]
coverageReporter = "lcov"
bash
# Ou via CLI
bun test --coverage --coverage-reporter=lcov

Le format LCOV est largement pris en charge par divers outils et services :

  • Éditeurs de code : Les extensions VS Code peuvent afficher la couverture en ligne
  • Services CI/CD : GitHub Actions, GitLab CI, CircleCI
  • Services de couverture : Codecov, Coveralls
  • IDEs : WebStorm, IntelliJ IDEA

Utiliser LCOV avec GitHub Actions

yaml
name: Test avec couverture
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
      - run: bun install
      - run: bun test --coverage --coverage-reporter=lcov
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage/lcov.info

Exclure des fichiers de la couverture

Ignorer les fichiers de test

Par défaut, les fichiers de test eux-mêmes sont inclus dans les rapports de couverture. Vous pouvez les exclure avec :

toml
[test]
coverageSkipTestFiles = true  # par défaut false

Cela exclura les fichiers correspondant aux motifs de test (par exemple *.test.ts, *.spec.js) du rapport de couverture.

Ignorer des chemins et motifs spécifiques

Vous pouvez exclure des fichiers spécifiques ou des motifs de fichiers des rapports de couverture en utilisant coveragePathIgnorePatterns :

toml
[test]
# Motif unique
coveragePathIgnorePatterns = "**/*.spec.ts"

# Plusieurs motifs
coveragePathIgnorePatterns = [
  "**/*.spec.ts",
  "**/*.test.ts",
  "src/utils/**",
  "*.config.js"
]

Cette option accepte les motifs glob et fonctionne de manière similaire aux motifs d'ignorance collectCoverageFrom de Jest. Les fichiers correspondant à l'un de ces motifs seront exclus du calcul et du reporting de couverture dans les sorties textuelles et LCOV.

Cas d'utilisation courants

toml
[test]
coveragePathIgnorePatterns = [
  # Exclure les fichiers utilitaires
  "src/utils/**",

  # Exclure les fichiers de configuration
  "*.config.js",
  "webpack.config.ts",
  "vite.config.ts",

  # Exclure les motifs de test spécifiques
  "**/*.spec.ts",
  "**/*.e2e.ts",

  # Exclure les artefacts de build
  "dist/**",
  "build/**",

  # Exclure les fichiers générés
  "src/generated/**",
  "**/*.generated.ts",

  # Exclure le code vendor/tiers
  "vendor/**",
  "third-party/**"
]

Sourcemaps

En interne, Bun transpile tous les fichiers par défaut, donc Bun génère automatiquement une source map interne qui mappe les lignes de votre code source original sur la représentation interne de Bun. Si pour une raison quelconque vous voulez désactiver cela, définissez test.coverageIgnoreSourcemaps à true ; cela sera rarement souhaitable en dehors de cas d'utilisation avancés.

toml
[test]
coverageIgnoreSourcemaps = true  # par défaut false

Valeurs par défaut de la couverture

Par défaut, les rapports de couverture :

  • Excluent les répertoires node_modules
  • Excluent les fichiers chargés via des loaders non-JS/TS (par exemple .css, .txt) sauf si un loader JS personnalisé est spécifié
  • Incluent les fichiers de test eux-mêmes (peut être désactivé avec coverageSkipTestFiles = true)
  • Peuvent exclure des fichiers supplémentaires avec coveragePathIgnorePatterns

Configuration avancée

Répertoire de couverture personnalisé

toml
[test]
coverageDir = "coverage-reports"  # par défaut "coverage"

Plusieurs reporters

toml
[test]
coverageReporter = ["text", "lcov"]

Couverture avec des motifs de test spécifiques

bash
# Exécuter la couverture uniquement sur des fichiers de test spécifiques
bun test --coverage src/components/*.test.ts

# Exécuter la couverture avec un motif de nom
bun test --coverage --test-name-pattern="API"

Intégration CI/CD

Exemple GitHub Actions

yaml
name: Rapport de couverture
on: [push, pull_request]

jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2

      - name: Install dependencies
        run: bun install

      - name: Run tests with coverage
        run: bun test --coverage --coverage-reporter=lcov

      - name: Upload to Codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage/lcov.info
          fail_ci_if_error: true

Exemple GitLab CI

yaml
test:coverage:
  stage: test
  script:
    - bun install
    - bun test --coverage --coverage-reporter=lcov
  coverage: '/Lines\s*:\s*(\d+.\d+)%/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/lcov.info

Interpréter les rapports de couverture

Explication de la sortie texte

-------------|---------|---------|-------------------
File         | % Funcs | % Lines | Uncovered Line #s
-------------|---------|---------|-------------------
All files    |   85.71 |   90.48 |
 src/        |   85.71 |   90.48 |
  utils.ts   |  100.00 |  100.00 |
  api.ts     |   75.00 |   85.71 | 15-18,25
  main.ts    |   80.00 |   88.89 | 42,50-52
-------------|---------|---------|-------------------
  • % Funcs : Pourcentage de fonctions appelées pendant les tests
  • % Lines : Pourcentage de lignes exécutables exécutées pendant les tests
  • Uncovered Line #s : Numéros de ligne spécifiques qui n'ont pas été exécutés

Ce qu'il faut viser

  • 80%+ de couverture globale : Généralement considéré comme bon
  • 90%+ de chemins critiques : La logique métier importante devrait être bien testée
  • 100% de fonctions utilitaires : Les fonctions pures et les utilitaires sont faciles à tester complètement
  • Couverture plus faible pour les composants UI : Souvent acceptable car ils peuvent nécessiter des tests d'intégration

Bonnes pratiques

Se concentrer sur la qualité, pas seulement la quantité

ts
// Bien : Tester la fonctionnalité réelle
test("calculateTax devrait gérer différents taux de taxe", () => {
  expect(calculateTax(100, 0.08)).toBe(8);
  expect(calculateTax(100, 0.1)).toBe(10);
  expect(calculateTax(0, 0.08)).toBe(0);
});

// Éviter : Juste atteindre les lignes pour la couverture
test("calculateTax existe", () => {
  calculateTax(100, 0.08); // Pas d'assertions !
});

Tester les cas limites

ts
test("validation des entrées utilisateur", () => {
  // Tester le cas normal
  expect(validateEmail("user@example.com")).toBe(true);

  // Tester les cas limites qui améliorent la couverture de manière significative
  expect(validateEmail("")).toBe(false);
  expect(validateEmail("invalid")).toBe(false);
  expect(validateEmail(null)).toBe(false);
});

Utiliser la couverture pour trouver des tests manquants

bash
# Exécuter la couverture pour identifier le code non testé
bun test --coverage

# Regarder les fichiers spécifiques qui nécessitent une attention
bun test --coverage src/critical-module.ts

Combiner avec d'autres métriques de qualité

La couverture n'est qu'une métrique. Considérez également :

  • Qualité de la revue de code
  • Couverture des tests d'intégration
  • Tests de gestion des erreurs
  • Tests de performance
  • Sécurité des types

Dépannage

La couverture ne s'affiche pas pour certains fichiers

Si des fichiers n'apparaissent pas dans les rapports de couverture, ils peuvent ne pas être importés par vos tests. La couverture ne suit que les fichiers qui sont réellement chargés.

ts
// Assurez-vous d'importer les modules que vous voulez tester
import { myFunction } from "../src/my-module";

test("ma fonction fonctionne", () => {
  expect(myFunction()).toBeDefined();
});

Rapports de couverture faux

Si vous voyez des rapports de couverture qui ne correspondent pas à vos attentes :

  1. Vérifiez que les source maps fonctionnent correctement
  2. Vérifiez les motifs de fichiers dans coveragePathIgnorePatterns
  3. Assurez-vous que les fichiers de test importent réellement le code à tester

Problèmes de performance avec les grandes codebases

Pour les grands projets, la collecte de couverture peut ralentir les tests :

toml
[test]
# Exclure les grands répertoires dont vous n'avez pas besoin de couverture
coveragePathIgnorePatterns = [
  "node_modules/**",
  "vendor/**",
  "generated/**"
]

Envisagez d'exécuter la couverture uniquement en CI ou sur des branches spécifiques plutôt qu'à chaque exécution de test pendant le développement.

Bun édité par www.bunjs.com.cn