bun test est profondément intégré au runtime de Bun. C'est en partie ce qui rend bun test rapide et simple à utiliser.
Variables d'environnement
NODE_ENV
bun test définit automatiquement $NODE_ENV sur "test" sauf s'il est déjà défini dans l'environnement ou via des fichiers .env. C'est un comportement standard pour la plupart des runners de tests et aide à assurer un comportement de test cohérent.
import { test, expect } from "bun:test";
test("NODE_ENV est défini sur test", () => {
expect(process.env.NODE_ENV).toBe("test");
});Vous pouvez remplacer cela en définissant NODE_ENV explicitement :
NODE_ENV=development bun testTZ (Fuseau horaire)
Par défaut, toutes les exécutions bun test utilisent UTC (Etc/UTC) comme fuseau horaire sauf s'il est remplacé par la variable d'environnement TZ. Cela assure un comportement cohérent des dates et heures dans différents environnements de développement.
import { test, expect } from "bun:test";
test("le fuseau horaire est UTC par défaut", () => {
const date = new Date();
expect(date.getTimezoneOffset()).toBe(0);
});Pour tester avec un fuseau horaire spécifique :
TZ=America/New_York bun testTimeouts des tests
Chaque test a un timeout par défaut de 5000ms (5 secondes) s'il n'est pas explicitement remplacé. Les tests qui dépassent ce timeout échoueront.
Timeout global
Changez le timeout globalement avec le drapeau --timeout :
bun test --timeout 10000 # 10 secondesTimeout par test
Définissez le timeout par test comme troisième paramètre de la fonction de test :
import { test, expect } from "bun:test";
test("test rapide", () => {
expect(1 + 1).toBe(2);
}, 1000); // timeout de 1 seconde
test("test lent", async () => {
await new Promise(resolve => setTimeout(resolve, 8000));
}, 10000); // timeout de 10 secondesTimeout infini
Utilisez 0 ou Infinity pour désactiver le timeout :
test("test sans timeout", async () => {
// Ce test peut s'exécuter indéfiniment
await someVeryLongOperation();
}, 0);Gestion des erreurs
Erreurs non gérées
bun test suit les rejets de promesse non gérés et les erreurs qui se produisent entre les tests. Si de telles erreurs se produisent, le code de sortie final sera non nul (spécifiquement, le nombre de telles erreurs), même si tous les tests réussissent.
Cela aide à détecter les erreurs dans le code asynchrone qui pourraient autrement passer inaperçues :
import { test } from "bun:test";
test("test 1", () => {
// Ce test réussit
expect(true).toBe(true);
});
// Cette erreur se produit en dehors de tout test
setTimeout(() => {
throw new Error("Erreur non gérée");
}, 0);
test("test 2", () => {
// Ce test réussit également
expect(true).toBe(true);
});
// L'exécution des tests échouera toujours avec un code de sortie non nul
// à cause de l'erreur non géréeRejets de promesse
Les rejets de promesse non gérés sont également capturés :
import { test } from "bun:test";
test("test réussissant", () => {
expect(1).toBe(1);
});
// Cela fera échouer l'exécution des tests
Promise.reject(new Error("Rejet non géré"));Gestion personnalisée des erreurs
Vous pouvez configurer des gestionnaires d'erreurs personnalisés dans votre configuration de test :
process.on("uncaughtException", error => {
console.error("Exception non attrapée :", error);
process.exit(1);
});
process.on("unhandledRejection", (reason, promise) => {
console.error("Rejet non géré à :", promise, "raison :", reason);
process.exit(1);
});Intégration des drapeaux CLI
Plusieurs drapeaux CLI de Bun peuvent être utilisés avec bun test pour modifier son comportement :
Utilisation de la mémoire
# Réduit l'utilisation de la mémoire pour la VM du runner de tests
bun test --smolDébogage
# Attache le débogueur au processus du runner de tests
bun test --inspect
bun test --inspect-brkChargement de modules
# Exécute des scripts avant les fichiers de test (utile pour la configuration/mocks globaux)
bun test --preload ./setup.ts
# Définit des constantes au moment de la compilation
bun test --define "process.env.API_URL='http://localhost:3000'"
# Configure des loaders personnalisés
bun test --loader .special:special-loader
# Utilise un tsconfig différent
bun test --tsconfig-override ./test-tsconfig.json
# Définit les conditions package.json pour la résolution de modules
bun test --conditions development
# Charge les variables d'environnement pour les tests
bun test --env-file .env.testDrapeaux liés à l'installation
# Affectent les requêtes réseau ou les installations automatiques pendant l'exécution des tests
bun test --prefer-offline
bun test --frozen-lockfileWatch et rechargement à chaud
Mode Watch
Lors de l'exécution de bun test avec le drapeau --watch, le runner de tests surveillera les changements de fichiers et ré-exécutera les tests affectés.
bun test --watchLe runner de tests est intelligent sur les tests à ré-exécuter :
import { add } from "./math.js";
import { test, expect } from "bun:test";
test("addition", () => {
expect(add(2, 3)).toBe(5);
});Si vous modifiez math.js, seul math.test.ts sera ré-exécuté, pas tous les tests.
Rechargement à chaud
Le drapeau --hot fournit des fonctionnalités similaires mais est plus agressif pour essayer de préserver l'état entre les exécutions :
bun test --hotPour la plupart des scénarios de test, --watch est l'option recommandée car elle fournit une meilleure isolation entre les exécutions de tests.
Variables globales
Les globaux suivants sont automatiquement disponibles dans les fichiers de test sans import (bien qu'ils puissent être importés de bun:test si préféré) :
// Tous ceux-ci sont disponibles globalement
test("fonction de test globale", () => {
expect(true).toBe(true);
});
describe("describe global", () => {
beforeAll(() => {
// beforeAll global
});
it("fonction it globale", () => {
// it est un alias pour test
});
});
// Compatibilité Jest
jest.fn();
// Compatibilité Vitest
vi.fn();Vous pouvez également les importer explicitement si vous préférez :
import { test, it, describe, expect, beforeAll, beforeEach, afterAll, afterEach, jest, vi } from "bun:test";Intégration de processus
Codes de sortie
bun test utilise des codes de sortie standard :
0: Tous les tests ont réussi, aucune erreur non gérée1: Des échecs de tests se sont produits>1: Nombre d'erreurs non gérées (même si les tests ont réussi)
Gestion des signaux
Le runner de tests gère correctement les signaux communs :
# Arrête gracieusement l'exécution des tests
kill -SIGTERM <pid-processus-test>
# Arrête immédiatement l'exécution des tests
kill -SIGKILL <pid-processus-test>Détection d'environnement
Bun détecte automatiquement certains environnements et ajuste le comportement :
// Détection GitHub Actions
if (process.env.GITHUB_ACTIONS) {
// Bun émet automatiquement des annotations GitHub Actions
}
// Détection CI
if (process.env.CI) {
// Certains comportements peuvent être ajustés pour les environnements CI
}Considérations de performance
Processus unique
Le runner de tests exécute tous les tests dans un seul processus par défaut. Cela fournit :
- Démarrage plus rapide - Pas besoin de lancer plusieurs processus
- Mémoire partagée - Utilisation efficace des ressources
- Débogage simple - Tous les tests dans un processus
Cependant, cela signifie :
- Les tests partagent l'état global (utilisez des hooks de cycle de vie pour nettoyer)
- Un plantage de test peut en affecter d'autres
- Pas de véritable parallélisation des tests individuels
Gestion de la mémoire
# Surveiller l'utilisation de la mémoire
bun test --smol # Réduit l'empreinte mémoire
# Pour les grandes suites de tests, envisagez de diviser les fichiers
bun test src/unit/
bun test src/integration/Isolation des tests
Puisque les tests s'exécutent dans le même processus, assurez un nettoyage approprié :
import { afterEach } from "bun:test";
afterEach(() => {
// Nettoyer l'état global
global.myGlobalVar = undefined;
delete process.env.TEST_VAR;
// Réinitialiser les modules si nécessaire
jest.resetModules();
});