# fast-check génère des cas limites dans vos tests JavaScript de blocs

> Présentation du test basé sur des propriétés côté JavaScript avec fast-check, pour générer automatiquement des cas limites qu'un développeur n'écrirait pas à la main.

- Auteur : WordPress Développement
- Publié le : 2024-04-30
- Mis à jour le : 2026-09-30
- Catégorie : Tests
- URL : https://www.wpmoderne.fr/tests/fast-check-genere-cas-limites-tests-js-blocs/

## L’essentiel

- Une propriété décrit un invariant, pas un exemple précis
- fast-check génère des centaines de cas, y compris les plus tordus
- Un échec fournit automatiquement le plus petit cas qui le reproduit

`test.each([0, 1, -1, 999999])('formate correctement %i', (valeur) => { ... })` — ce style de test par exemples fixes couvre les cas auxquels le développeur a pensé, jamais ceux auxquels il n'a pas pensé. Sur un bloc Gutenberg de calcul de remise progressive pour un site de vente d'articles de sport d'occasion, cette approche laissait passer un cas limite précis : une remise calculée sur une quantité négative, jamais testée parce que jugée impossible à tort côté interface.

Le test basé sur des propriétés inverse la logique habituelle : plutôt que de fournir des exemples, on décrit une propriété qui doit rester vraie pour n'importe quelle entrée valide, et l'outil génère lui-même des centaines de valeurs, y compris des cas limites qu'un développeur n'aurait pas envisagés spontanément.

## Écrire une propriété plutôt qu'un exemple

La bibliothèque fast-check permet de définir un espace de valeurs possibles, puis une propriété qui doit tenir pour toutes ces valeurs :

```
import fc from 'fast-check';
import { calculerRemiseProgressive } from '../remise';

test('la remise ne dépasse jamais le prix total, quelle que soit la quantité', () => {
  fc.assert(
    fc.property(
      fc.integer({ min: -10, max: 1000 }),
      fc.float({ min: 0.01, max: 500, noNaN: true }),
      (quantite, prixUnitaire) => {
        const remise = calculerRemiseProgressive(quantite, prixUnitaire);
        const total = quantite > 0 ? quantite * prixUnitaire : 0;
        return remise <= total;
      }
    )
  );
});
```

## Ce que fast-check a trouvé automatiquement

> L'essentiel à retenir : Une propriété décrit un invariant, pas un exemple précis ; fast-check génère des centaines de cas, y compris les plus tordus ; Un échec fournit automatiquement le plus petit cas qui le reproduit

Dès la première exécution, fast-check a produit un échec avec une quantité de `-3`, révélant que `calculerRemiseProgressive` renvoyait une remise positive même pour une quantité négative, un cas censé ne jamais se produire côté interface mais atteignable via un appel direct à l'API REST du bloc.

```
Property failed after 1 tests
{ seed: 1714000000, path: "0:0", endOnFailure: true }
Counterexample: [-3, 12.5]
Shrunk 4 time(s)
Got: -37.5
```

La mention « Shrunk 4 time(s) » indique que fast-check a automatiquement réduit le cas d'échec initial, souvent plus complexe, jusqu'au cas le plus simple qui reproduit encore le problème. Cette réduction automatique évite au développeur de devoir lui-même simplifier un cas d'échec compliqué pour comprendre la cause.

## Le correctif appliqué

La fonction ne validait pas que la quantité soit strictement positive avant de calculer la remise :

```
function calculerRemiseProgressive(quantite, prixUnitaire) {
  if (quantite <= 0) {
    return 0;
  }
  // logique de calcul existante, inchangée
}
```

## Choisir les bonnes propriétés à tester

Une propriété utile décrit un invariant vrai pour toutes les entrées, pas un résultat précis. Sur ce projet, trois propriétés ont été retenues comme les plus rentables à tester ainsi :

- La remise ne dépasse jamais le montant total, quelle que soit la combinaison de quantité et de prix.
- Le montant final après remise reste toujours positif ou nul, jamais négatif.
- Doubler la quantité ne peut jamais réduire le montant final par rapport à la quantité initiale (propriété de monotonie).

## Limites de l'approche

Le test basé sur des propriétés ne remplace pas les exemples fixes documentant un cas métier précis et attendu : les deux approches se complètent, l'une couvrant l'espace large des entrées possibles, l'autre fixant un comportement de référence lisible pour un futur relecteur. Cette approche ne traite ici que le code JavaScript côté bloc ; son équivalent côté PHP, la bibliothèque Eris, repose sur des principes similaires mais une syntaxe différente, hors du périmètre de cet article.

### Le coût d'exécution, un compromis à surveiller

Générer une centaine de cas à chaque exécution ralentit mécaniquement la suite de tests par rapport à quatre exemples fixes exécutés instantanément. Sur ce projet, ce ralentissement est resté négligeable (quelques centaines de millisecondes supplémentaires par propriété testée), mais une équipe qui multiplierait les propriétés sur l'ensemble de ses blocs devrait surveiller le temps total de la suite, quitte à réduire le nombre de cas générés en local et à le relever uniquement dans le pipeline d'intégration continue, où le temps disponible est généralement moins contraint.

> Un exemple fixe prouve qu'un cas fonctionne ; une propriété prouve qu'aucun cas ne devrait pouvoir la violer.

## En résumé

fast-check a permis de découvrir, dès la première exécution, un bug de calcul jamais atteint par les tests par exemples fixes écrits à la main. Sur ce bloc de remise progressive, une seule propriété bien choisie a généré plus de cas de test qu'une semaine entière d'écriture manuelle d'exemples n'aurait pu couvrir.
