dart-matcher-best-practices

Je remarque que vous avez fourni "|-" ce qui semble être un début incomplet de tableau Markdown. Pouvez-vous s'il vous plaît fournir le texte complet à traduire ? Je suis prêt à : 1. Traduire le contenu en français 2. Préserver strictement le formatage Markdown 3. Conserver les noms propres, marques et commandes techniques en anglais 4. Retourner uniquement la traduction Veuillez partager le texte que vous souhaitez faire traduire.

npx skills add https://github.com/flutter/skills --skill dart-matcher-best-practices

Bonnes pratiques Dart Matcher

Quand utiliser cette compétence

Utilisez cette compétence lorsque :

  • Vous écrivez des assertions en utilisant expect et package:matcher.
  • Vous migrez des vérifications manuelles héritées vers des matchers plus propres.
  • Vous déboguez des échecs de test confus.

Découverte

Pour trouver des candidats à l'amélioration de l'utilisation des matchers, recherchez des motifs sous-optimaux :

Vérifications de longueur sous-optimales

Recherchez les vérifications de longueur qui devraient utiliser hasLength :

  • Regex : expect\([^,]+.length,\s*

Vérifications booléennes sous-optimales

Recherchez les vérifications sur les propriétés booléennes qui ont des matchers spécifiques :

  • Regex : expect\([^,]+.isEmpty,\s*(true|equals\(true\))
  • Regex : expect\([^,]+.isNotEmpty,\s*(true|equals\(true\))
  • Regex : expect\([^,]+.contains\(.*\),\s*(true|equals\(true\))

Recherches de map sous-optimales

Recherchez les recherches manuelles de map au lieu d'utiliser containsPair :

  • Regex : expect\([^,]+\[.*\],\s*

Matchers principaux

1. Collections (hasLength, contains, isEmpty, unorderedEquals, containsPair)

  • hasLength(n) :

    • Préférez expect(list, hasLength(n)) à expect(list.length, n).
    • Donne de meilleurs messages d'erreur en cas d'échec (affiche le contenu réel de la liste).
  • isEmpty / isNotEmpty :

    • Préférez expect(list, isEmpty) à expect(list.isEmpty, true).
    • Préférez expect(list, isNotEmpty) à expect(list.isNotEmpty, true).
  • contains(item) :

    • Vérifiez l'existence sans itération manuelle.
    • Préférez à expect(list.contains(item), true).
  • unorderedEquals(items) :

    • Vérifiez le contenu indépendamment de l'ordre.
    • Préférez à expect(list, containsAll(items)).
  • containsPair(key, value) :

    • Vérifiez qu'une map contient une paire clé-valeur spécifique.
    • Préférez à la vérification de expect(map[key], value) ou expect(map.containsKey(key), true).

2. Vérifications de type (isA<T> et TypeMatcher<T>)

  • isA<T>() :

    • Préférez pour les assertions en ligne : expect(obj, isA<Type>()).
    • Plus concis et lisible que TypeMatcher<Type>().
    • Permet le chaînage des contraintes en utilisant .having().
  • TypeMatcher<T> :

    • Préférez pour définir des matchers réutilisables au niveau supérieur.
    • Utilisez const : const isMyType = TypeMatcher<MyType>();
    • Le chaînage de .having() fonctionne ici aussi, mais le matcher résultant n'est pas const.

3. Propriétés d'objet (having)

Utilisez .having() sur isA<T>() ou d'autres TypeMatchers pour vérifier les propriétés.

  • Noms explicites : Utilisez des noms de paramètres explicites dans la closure (par exemple, (e) => e.message) au lieu de noms génériques comme p0 pour améliorer la lisibilité.
expect(person, isA<Person>()
    .having((p) => p.name, 'name', 'Alice')
    .having((p) => p.age, 'age', greaterThan(18)));

Cela fournit des messages d'échec détaillés indiquant exactement quelle propriété a échoué.

4. Assertions asynchrones

  • completion(matcher) :

    • Attendez la fin d'une future et vérifiez sa valeur.
    • Préférez await expectLater(...) pour vous assurer que la future se termine avant que le test continue.
    • await expectLater(future, completion(equals(42))).
  • throwsA(matcher) :

    • Vérifiez qu'une future ou une fonction lève une exception.
    • await expectLater(future, throwsA(isA<StateError>())).
    • expect(() => function(), throwsA(isA<ArgumentError>())) (une fonction synchrone qui lance une exception va bien avec expect).

5. Utiliser expectLater

Utilisez await expectLater(...) lors du test du comportement asynchrone pour assurer un séquençage approprié.

// BON : Attend que la future se termine avant de vérifier les effets secondaires
await expectLater(future, completion(equals(42)));
expect(sideEffectState, equals('done'));

// MAUVAIS : La vérification des effets secondaires pourrait s'exécuter avant la fin de la future
expect(future, completion(equals(42)));
expect(sideEffectState, equals('done')); // Condition de course !

Principes

  1. Échecs lisibles : Choisissez les matchers qui produisent des messages d'erreur clairs.
  2. Évitez la logique manuelle : N'utilisez pas d'instructions if ou de boucles for pour les assertions ; laissez les matchers s'en charger.
  3. Matchers spécifiques : Utilisez le matcher le plus spécifique disponible (par exemple, containsPair pour les maps au lieu de vérifier les clés manuellement).

Compétences associées

  • dart-test-fundamentals : Concepts clés pour structurer les tests, les cycles de vie et la configuration.
  • dart-checks-migration : Utilisez cette compétence si vous migrez les tests de package:matcher vers le moderne package:checks.