Nunit: Test d'instantané à la manière d'une plaisanterie

Créé le 29 août 2017  ·  20Commentaires  ·  Source: nunit/nunit

Bonjour,
Je me demandais si la communauté souhaitait introduire une nouvelle fonctionnalité dans NUnit - Snapshot Testing. Ce type de test a gagné du terrain depuis le framework Jest et vous pouvez en savoir plus ici . Essentiellement, quel que soit le blob que vous voulez vous assurer qu'il ne change pas dans le cadre d'un test unitaire, vous pouvez prendre un "instantané" par le biais d'une certaine manière de sérialisation. Cet instantané est ensuite ajouté à votre code source. Lorsque le blob sous-jacent change, le test d'instantané échoue et vous avez la possibilité de mettre à jour l'instantané ou de réparer ce qui s'est cassé. L'un des principaux avantages de ceci est une belle différence visuelle lorsque quelque chose dans le blob change, car cela fait partie du contrôle de source. Les pensées?

idea

Commentaire le plus utile

Salut,
depuis que ce ticket ici est devenu obsolète, j'ai récemment ajouté le support NUnit à https://github.com/theramis/Snapper

Tous les 20 commentaires

J'ai voulu générer et différencier des fichiers d'API publics et échouer sur des modifications non approuvées. Il semblerait que cela irait dans le même sens.

Il serait utile d'avoir des exemples de ce à quoi cela ressemble d'écrire _manuellement_ des tests d'instantanés aujourd'hui dans NUnit pour les types de tests d'instantanés que vous avez à l'esprit, ainsi que ce que vous préféreriez écrire. Cela semble être le genre de chose qui devrait peut-être commencer comme une extension communautaire.

Je suis d'accord avec Joseph - je pense que c'est une excellente possibilité d'extension. Du côté de NUnit, nous devons nous assurer que nos interfaces peuvent prendre en charge un tel outil.

C'est une idée intéressante, mais comme les autres, j'aimerais voir des exemples de ce à quoi cela ressemblerait dans le NUnit actuel et à quoi vous proposez qu'il ressemblerait avec cette fonctionnalité.

Ainsi, la première fois que vous vérifiez un instantané, s'il n'existe pas, un instantané est pris et ajouté à un fichier qui est utilisé par vos tests pour les exécutions suivantes. Nous aurions du mal à ajouter ces instantanés au projet, de sorte qu'ils ne seraient pas automatiquement ajoutés au contrôle de source pour les personnes utilisant TFS, mais git ne serait pas un problème.

Nous devrons également décider comment sérialiser l'instantané et quels types de données il prend en charge. Le choix évident serait JSON, mais nous ne voulons pas dépendre d'une bibliothèque externe pour la sérialisation JSON. @lilasquared que proposeriez-vous ?

@rprouse Je vais essayer de créer un exemple à partager.

@ jnm2 J'ai d'abord pensé à l'idée qu'il s'agissait d'une extension, mais la création/la mise à jour des fichiers d'instantanés peut être délicate du point de vue de l'extension. Jest est lancé à partir de la ligne de commande et lorsqu'un test échoue, il vous donne la possibilité de mettre à jour les instantanés un par un ou de mettre à jour en masse lors de la prochaine exécution. Je ne sais pas comment ce type de fonctionnalité fonctionnerait au sein des coureurs nunit et du studio visuel. À cause de cela, je ne connais pas de bon moyen d'en faire une extension.

En ce qui concerne la sérialisation - je n'y ai pas beaucoup réfléchi car JSON était le choix évident, même si je peux voir pourquoi avoir une dépendance externe pourrait être un problème. Il pourrait être implémenté pour accepter une forme de données déjà sérialisée pour l'instantané, puis compter sur le consommateur pour déterminer comment il souhaite sérialiser (xml, json, méthode .ToString() , etc.). Je pouvais alors voir l'extension NUnit.Snapshot.Json existante qui ajoute la dépendance json et implémente une méthode .MatchesSnapshotJson() ou quelque chose de cette nature.

Un exemple serait vraiment utile ici. Je ne sais même pas s'il s'agit d'une fonctionnalité pour le cadre, le moteur, les coureurs ou une combinaison. :smiley:

@CharliePoole cela peut nécessiter une combinaison ! Les coureurs auraient besoin de pouvoir mettre à jour les instantanés générés par les tests eux-mêmes.

Ce serait une bonne idée de vérifier également les exemples de Jest. Je vais essayer d'en trouver un qui ait du sens, mais leurs exemples et leur documentation sont plutôt bons. L'un de ses avantages est de visualiser le résultat rendu d'un composant de réaction. Lorsque le composant change, vous obtenez un visuel vraiment agréable à partir de l'instantané pour voir exactement ce qui change.

Serait-il correct de dire que cela ne s'applique qu'aux coureurs interactifs ?

@CharliePoole si je comprends votre question alors oui. Je ne m'attendrais pas à ce que certains systèmes automatisés exécutant des tests mettent à jour les instantanés. Les instantanés seraient mis à jour au cours du développement par le développeur.

@lilasquared Dans ce cas, il y a peut-être deux fonctionnalités ici : le test d'instantané et la mise à jour d'instantané.

Il pourrait être divisé de cette façon, mais il serait impossible de faire des tests instantanés sans mise à jour. La partie test ferait partie du cadre et la mise à jour ferait partie du coureur. Si c'est ce dont vous parlez, alors oui, ses deux fonctionnalités

Oui, c'est ce que je voulais dire. Diviser et conquérir. Il est possible qu'une partie de la partie du coureur soit dans le moteur, ce qui rend le support du coureur beaucoup plus facile.

@rprouse @CharliePoole J'ai créé des exemples simples super morts ainsi qu'une implémentation très naïve utilisant un SnapshotConstraint qui fait un travail super simple pour générer un instantané. vérifiez-le et faites-moi savoir si vous souhaitez des exemples plus complexes.

edit: et je les mets ici https://github.com/lilasquared/NUnitSnapshotExample

@lilasquared Cool ! C'est une belle encapsulation de ce que nous appelions le "Gold Master". Est-ce que les gens disent encore ça ? 😄

La technique a évidemment trois aspects.

  1. Comparer avec le maître. Le framework NUnit pourrait le faire via une contrainte, comme vous l'avez fait.
  2. Enregistrement du maître s'il n'existe pas déjà. Cela doit également être fait dans le cadre.
  3. Mise à jour du maître si le résultat attendu a changé. C'est la partie interactive. Il doit être dans un coureur et ce coureur a deux façons de procéder :
    3.1 Relancez le test, en passant un argument qui l'indique au nouveau maître, même s'il ne correspond pas.
    3.2 Enregistrez directement le nouveau maître, ce qui nécessite qu'il sache comment fonctionne le framework et comment il enregistre ces maîtres.

Ma préférence dans la troisième étape est 3.1, car cela permettrait au coureur de travailler avec différents frameworks sans savoir exactement comment ni où ils enregistrent les instantanés. NUnit le fait déjà un peu, en passant les paramètres du framework dans le TestPackage qui sont honorés par le framework NUnit 3 mais ignorés par tout autre.

@CharliePoole Merci pour les commentaires ! Je pense que pour les parties 1 et 2, j'ai une bonne idée de ce qui doit être fait et comment le faire. J'ai mis à jour les exemples avec des fonctionnalités un peu plus robustes et extensibles, ainsi que la façon dont j'imagine que la sérialisation json pourrait fonctionner comme une extension. Il me faudrait un certain temps pour comprendre comment l'intégrer dans NUnit.Framework et pour qu'il soit cohérent avec les modèles de conception utilisés là-bas.
La partie 3 va être difficile pour moi d'essayer de faire aussi bien à moins que quelqu'un de plus familier avec cela ait intérêt à aider. Une question que j'ai est que vous avez mentionné les paramètres TestPackage , mais je ne vois pas comment je peux accéder à ces paramètres dans le contexte d'une contrainte. Je suppose que la partie 3.1 implique que la contrainte, qui est responsable de la sauvegarde des nouveaux instantanés, serait également responsable de leur mise à jour étant donné l'argument de commande approprié du coureur.

Nous en avons également parlé comme d'une extension et c'est essentiellement ce que j'ai créé dans l'exemple. Il est fonctionnel mais les instantanés devraient être supprimés manuellement à chaque fois et le test relancé pour enregistrer le nouveau. Je pense que l'intégrer dans le coureur a en quelque sorte plus de sens.

C'est vraiment poussé, mais ce serait cool si j'avais la possibilité de stocker l'instantané dans un fichier C # à côté du code. L'extension devrait prendre une dépendance sur Roslyn afin de mettre à jour l'instantané. Pour l'instant, une chimère. =)

@ jnm2 C'est plus ou moins ainsi que fonctionne l'implémentation de plaisanterie mais avec un fichier javascript. Javascript facilite cette opération et exporte les instantanés à partir du fichier généré automatiquement. Ce serait certainement super cool. Il pourrait s'agir d'une extension un peu comme l'extension Json que j'ai montrée qui implémente simplement son propre ISnapshotCache

Je viens de remarquer les liens, je vais suivre ceux-ci...

Salut,
depuis que ce ticket ici est devenu obsolète, j'ai récemment ajouté le support NUnit à https://github.com/theramis/Snapper

Je ferme les anciens numéros d'idées qui n'ont pas fait l'objet de commentaires ou qui n'ont pas progressé depuis plusieurs années. Si quelqu'un revient avec un argument convaincant pour ces questions, nous pouvons rouvrir.

Cette page vous a été utile?
0 / 5 - 0 notes