---
title: "Assertion dupliquée"
type: "test-smell"
slug: "duplicate-assert"
url: "http://localhost:3000/fr/test-smells/duplicate-assert.md"
category: "Odeurs d'assertion"
description: "Une seule méthode de test vérifie plusieurs fois la même condition — en répétant une assertion identique ou en revérifiant une logique équivalente — au lieu de supprimer la vérification redondante ou de répartir les cas distincts dans leurs propres tests ciblés."
---
# Assertion dupliquée

> Une seule méthode de test vérifie plusieurs fois la même condition — en répétant une assertion identique ou en revérifiant une logique équivalente — au lieu de supprimer la vérification redondante ou de répartir les cas distincts dans leurs propres tests ciblés.

## Signs and Symptoms

Vous voyez la **même assertion apparaître deux fois** (même matcher, mêmes arguments) dans un test, ou plusieurs blocs d'assertions copiés‑collés qui ne diffèrent que par des valeurs littérales et qui re‑testent le _même_ comportement. Signes révélateurs :

* Une ligne d'assertion littéralement identique apparaît deux fois ou plus dans le corps.
* De nombreux appels `expect(...)`/`assertEquals(...)` exerçant la même condition avec des entrées différentes, tous entassés dans une seule méthode dont le nom ne décrit qu'un seul scénario.
* Des assertions résiduelles issues du débogage (« laisse-moi aussi vérifier X ») qui n'ont jamais été nettoyées.
* Le nom du test (par ex. `testXmlSanitizer`) ne donne aucun indice sur laquelle de ses nombreuses vérifications a échoué.

```js
test('sanitizer accepts valid input', () => {
  expect(isValid('plain text')).toBe(true);
  expect(isValid('with spaces')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true);   // "le moins est valide"
  expect(isValid('Fritz-box')).toBe(true);   // <-- doublon exact, n'apporte rien
  expect(isValid('<script>')).toBe(false);
});

```

La ligne `Fritz-box` dupliquée est l'exemple canonique de l'Assertion dupliquée ; le smell plus large est qu'une seule méthode regroupe silencieusement de nombreuses vérifications de même condition sous un seul nom.

## Reasons for the Problem

**Pourquoi cela se produit**

* **Copier‑coller.** Un bloc d'assertions est dupliqué et les littéraux (voire rien) sont modifiés.
* **Résidu de débogage.** Des assertions supplémentaires ajoutées pour sonder le comportement sont laissées en place.
* **Regroupement.** Les développeurs testent « une méthode » en empilant tous les cas dans un seul test au lieu de les répartir, produisant des vérifications répétées et presque identiques.

**Pourquoi c'est nuisible**

* **Fausse assurance.** Une assertion réellement identique et dupliquée ajoute _zéro_ couverture — elle ne peut jamais échouer lorsque sa jumelle réussit — mais elle fait paraître le test plus rigoureux qu'il ne l'est.
* **Diagnostic d'échec difficile.** Lorsque plusieurs assertions de même forme partagent une seule méthode, un rapport d'échec pointe vers la méthode, pas vers l'entrée spécifique qui a échoué. Pire, un test en configuration par défaut s'arrête à la première assertion qui échoue, de sorte que les vérifications dupliquées suivantes ne s'exécutent jamais — vous en corrigez une, relancez, tombez sur la suivante (recoupe le smell _Roulette d'assertions_).
* **Mauvaise lisibilité.** Le lecteur ne peut pas dire si la répétition est intentionnelle (cas distincts) ou une erreur (vraie duplication), et le nom du test ne documente qu'une seule des nombreuses conditions.
* **Coût de maintenance.** Modifiez le comportement testé et vous devez traquer et mettre à jour chaque assertion dupliquée ; en oubliez une et la suite de tests devient incohérente.

## Treatment

1. **Supprimez les doublons exacts.** Si une assertion est identique octet pour octet à une autre dans le même test, retirez-la — c'est du poids mort, pas de la couverture.
2. **Paramétrez les cas équivalents.** Lorsque les « doublons » sont en réalité la _même_ condition avec des _entrées différentes_, convertissez-les en un test paramétré/tabulaire (`test.each` dans Jest/Vitest, `@ParameterizedTest` dans JUnit 5). Chaque ligne est rapportée et nommée séparément, de sorte que les échecs identifient précisément l'entrée fautive.
3. **Répartissez les conditions réellement différentes** dans des tests distincts, chacun portant un nom qui indique ce qu'il vérifie (`accepte les noms d'hôte avec trait d'union`, `rejette les balises script`).
4. **Nommez selon l'intention.** Un nom de test doit décrire un comportement ; si vous n'y arrivez pas, c'est un signal qu'il faut le scinder.

```js
// Avant — assertions dupliquées / regroupées dans un test opaque
test('isValid', () => {
  expect(isValid('plain text')).toBe(true);
  expect(isValid('with spaces')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true);
  expect(isValid('Fritz-box')).toBe(true); // doublon
  expect(isValid('<script>')).toBe(false);
});

// Après — une seule assertion, chaque cas nommé et rapporté indépendamment
test.each([
  ['plain text', true],
  ['with spaces', true],
  ['Fritz-box',  true],   // le moins est valide
  ['<script>',   false],  // rejette le balisage
])('isValid(%j) === %s', (input, expected) => {
  expect(isValid(input)).toBe(expected);
});

```

La ligne dupliquée a disparu, les entrées distinctes sont explicites, et un échec nomme le cas exact.
