JustDummies

Juste des dummies, mais redoutablement efficaces.

Pourquoi JustDummies

JustDummies produit les valeurs arbitraires dont un test a besoin, et vous laisse énoncer les règles que ces valeurs doivent respecter.

Dans un test, toutes les valeurs ne portent pas le scénario. Celles qui ne le portent pas doivent quand même respecter les règles du domaine — c'est cette partie-là que JustDummies prend en charge. Voir l'exemple complet, étape par étape.

Lequel de ces besoins est le vôtre ?

Ces quatre réponses passent souvent pour des rivales. Elles répondent à quatre questions différentes, et la plupart des projets s'en posent plusieurs. Cherchez la phrase que vous diriez à voix haute.

JustDummies

Peu m'importe cette valeur, mais elle doit être valide.

Des valeurs arbitraires pour tout ce qu'un test ne vérifie pas, avec les règles qu'elles doivent respecter, écrites là où le test demande la valeur.

Concrètement : une référence commençant toujours par ORD-, alphanumérique en majuscules après ce préfixe, d'une longueur comprise entre huit et vingt caractères, et tirée à chaque exécution.

Voir le dépôt ouvre un nouvel onglet

Bogus

J'ai besoin de données qui ont l'air vraies.

Un générateur simple de fausses données pour C#, F# et VB.NET — le portage du célèbre faker.js.

Concrètement : des noms, des adresses, des e-mails, des numéros de téléphone, des libellés de produits — adaptés à la locale, et crédibles pour qui regarde une capture d'écran ou une base de démonstration.

Voir le dépôt ouvre un nouvel onglet

AutoFixture

Construisez-moi l'objet, son contenu m'est égal.

Une bibliothèque qui vous dispense d'écrire à la main les variables anonymes dont la préparation d'un test a besoin.

Concrètement : un appel renvoie un objet entièrement rempli, y compris tout ce qu'il contient et les types dont vous n'avez pas le code — sans que vous ayez rien déclaré nulle part.

Voir le dépôt ouvre un nouvel onglet

Valeur en dur

Cette valeur précise, c'est ce que le test vérifie.

Aucune bibliothèque : la valeur tapée directement dans le test, sur la ligne qui l'utilise.

Concrètement : le montant qu'une assertion compare, ou le statut dont dépend un comportement. Le lecteur le voit sans quitter le test.

JustDummies face aux alternatives

Dix critères, chacun posé comme une question sur vos propres tests, puis tranché pour les quatre options.

Ce que veut dire chaque réponse
Conçu pour ça
L'outil est fait pour ça, et il le fait sans configuration supplémentaire.
Possible, avec du travail
On y arrive, mais il faut écrire quelque chose pour y arriver. La note dit quoi.
Ce n'est pas son rôle
L'outil ne le fait pas. Parfois parce que ses auteurs en ont décidé ainsi, parfois parce que personne ne l'a encore écrit — la note précise lequel des deux.

Tableau comparatif complet

Toutes les réponses en un coup d'œil, sans leurs notes. Chaque critère renvoie au bloc qui l'explique plus bas.

  • Conçu pour ça
  • Possible, avec du travail
  • Ce n'est pas son rôle
Quatre façons d'obtenir une valeur de test, critère par critère.
CritèreJustDummiesBogusAutoFixtureValeur en dur
La valeur passera-t-elle mon propre code ?
Les valeurs que votre code accepteConçu pour çaPossible, avec du travailPossible, avec du travailPossible, avec du travail
Des règles énoncées sur placeConçu pour çaPossible, avec du travailPossible, avec du travailCe n'est pas son rôle
Remplir les objets imbriqués à votre placePossible, avec du travailPossible, avec du travailConçu pour çaPossible, avec du travail
Mon test restera-t-il lisible ?
Voir quelle valeur le test vérifieConçu pour çaPossible, avec du travailConçu pour çaPossible, avec du travail
Décrire un objet valide une seule foisPossible, avec du travailPossible, avec du travailPossible, avec du travailPossible, avec du travail
De quelle nature de valeur ai-je besoin ?
Des données vraisemblablesCe n'est pas son rôleConçu pour çaCe n'est pas son rôlePossible, avec du travail
Chercher la valeur qui casse votre codeCe n'est pas son rôleCe n'est pas son rôleCe n'est pas son rôleCe n'est pas son rôle
Que se passe-t-il quand ça casse, et qui écrit la préparation ?
Rejouer l'exécution qui a échouéConçu pour çaConçu pour çaCe n'est pas son rôleConçu pour ça
Détecté avant même de lancer le testConçu pour çaPossible, avec du travailCe n'est pas son rôleCe n'est pas son rôle
Un outil qui écrit la préparation pour vousConçu pour çaPossible, avec du travailCe n'est pas son rôleCe n'est pas son rôle

Les critères sont regroupés selon les questions que vous pouvez vous poser dans vos tests, pas selon les points forts de JustDummies. Et JustDummies ne cherche volontairement pas à répondre à tous les besoins : son objectif est de bien faire une seule chose, générer les valeurs arbitraires et contraintes dont vos tests ont besoin.

La valeur passera-t-elle mon propre code ?

Les valeurs que votre code accepte

La valeur produite passera-t-elle mon propre constructeur ?

La plupart des types du domaine refusent ce qui ne leur convient pas. OrderReference.Create rejette une chaîne qui ne commence pas par ORD-, celles qui font moins de huit caractères ou plus de vingt, et celles qui portent après le préfixe autre chose qu'une lettre majuscule ou un chiffre. Un test qui a besoin d'une référence quelconque a quand même besoin d'une référence qui passe tous ces contrôles.

Terme technique : invariant métier, ou précondition en design par contrat

string reference = Any.String()
                      .AlphaNumeric()
                      .InUpperCase()
                      .StartingWith("ORD-")
                      .WithLengthBetween(8, 20)
                      .Generate();
produit, exécution après exécutionORD-KOKR06JCSSORD-BHW5BL44FJC1VORD-WZYMJV2FMORD-A243EM1HKJJEEB3
  • JustDummiesConçu pour ça
  • BogusPossible, avec du travail

    Un Faker<T> respecte une règle métier dès qu'un RuleFor est écrit pour elle — ou un CustomInstantiator qui appelle la fabrique du type. StrictMode(true) vérifie ensuite que chaque propriété a bien une règle. Ce qu'aucun contrôle ne couvre, c'est de savoir si une règle produit une valeur que le domaine accepterait.

  • AutoFixturePossible, avec du travail

    Une règle que le type porte sous forme d'annotation — [Range], [StringLength], [RegularExpression] — est déjà respectée, sans aucune configuration. Une règle appliquée à l'intérieur d'un constructeur, c'est l'autre cas : la génération échoue tant qu'un Register, un Customize<T> ou un ISpecimenBuilder n'a pas été écrit pour la satisfaire.

  • Valeur en durPossible, avec du travail

    La valeur est valide parce que quelqu'un l'a choisie ainsi, et pour cette seule raison. Rien ne vérifie qu'elle l'est restée depuis.

Des règles énoncées sur place

Puis-je écrire « un nombre quelconque entre 1 et 100 » sur la ligne qui en a besoin ?

Certaines règles appartiennent à un test plutôt qu'au domaine : cette quantité vaut au moins deux, cette date est passée. La question est de savoir si vous pouvez le dire là où le test demande la valeur, ou s'il faut d'abord déclarer un type, enregistrer une configuration ou monter une fixture.

Terme technique : point d'appel — l'endroit exact du code où la valeur est demandée

int quantity = Any.Int32().Between(1, 100).Generate();
produit, exécution après exécution91596442
  • JustDummiesConçu pour ça
  • BogusPossible, avec du travail

    Un Faker<T> peut être construit sur place dans le test, juste avant Generate, avec ses règles dessus — Random.Int(min, max) et consorts. Il faut simplement les réécrire dans chaque test qui en a besoin.

  • AutoFixturePossible, avec du travail

    Une règle portée par le type est respectée partout, sans une ligne dans le test. Une règle propre à ce test-là s'écrit sur place via Build<T>().With(x => x.Prop, value) — une valeur épinglée, ou une lambda que vous écrivez, une propriété à la fois.

  • Valeur en durCe n'est pas son rôle

    La règle n'est jamais énoncée. Vous choisissez une valeur qui la respecte, et la règle reste dans la tête de celui qui l'a choisie.

Remplir les objets imbriqués à votre place

Mon type a trois niveaux d'imbrication et le test ne s'intéresse à aucun : qui les remplit ?

Une commande contient un client, qui contient une adresse. Soit un outil inspecte votre classe et remplit tous les niveaux, soit vous fournissez un générateur par type et vous les assemblez.

Terme technique : graphe d'objets

  • JustDummiesPossible, avec du travail

    Vous fournissez un générateur par type et vous les composez. Rien n'inspecte votre classe pour remplir les niveaux du dessous.

  • BogusPossible, avec du travail

    Un objet imbriqué se construit à la main, dans la règle qui le produit. Bogus n'y descend pas à votre place.

  • AutoFixtureConçu pour ça
  • Valeur en durPossible, avec du travail

    Chaque objet imbriqué se construit à la main, niveau par niveau, et le constructeur de chacun est une ligne que vous écrivez puis maintenez.

Mon test restera-t-il lisible ?

Voir quelle valeur le test vérifie

Un lecteur peut-il dire de quelles valeurs dépend l'assertion ?

Un test qui construit une commande à partir de quatre arguments ne dit pas sur lequel des quatre il porte. En tirer trois et écrire le quatrième en clair répond à la question dans la préparation elle-même.

  • JustDummiesConçu pour ça
  • BogusPossible, avec du travail

    RuleFor(x => x.Prop, expected) épingle la valeur exacte que vérifie l'assertion : le sujet du test est donc écrit noir sur blanc. Les règles autour le sont tout autant.

  • AutoFixtureConçu pour ça

    C'est l'objectif qu'AutoFixture se donne lui-même : les valeurs dont le test se moque disparaissent, parce que vous ne les décrivez jamais. Ce qui disparaît avec elles, c'est tout énoncé de ce que ces valeurs doivent respecter.

  • Valeur en durPossible, avec du travail

    Elle montre sans détour la valeur qui est le sujet du test. Employée aussi pour les paramètres autour, la préparation gagne une ligne par paramètre, et le sujet cesse de ressortir.

Décrire un objet valide une seule fois

Le jour où mon type gagne un paramètre de constructeur, combien de fichiers de test dois-je rouvrir ?

Ce qui décrit une commande valide — une chaîne de contraintes, un jeu de règles, un builder — mérite d'être écrit une fois et appelé partout. La question est de savoir ce que cela coûte à mettre en place, et quelle part l'outil en écrit pour vous.

  • JustDummiesPossible, avec du travail

    Il faut d'abord écrire le générateur, dans votre propre projet de test ; ensuite, tous vos tests l'appellent. L'outil dum — le CLI compagnon de la bibliothèque — peut écrire ce fichier pour vous. Un simple appel ne le fait pas apparaître.

  • BogusPossible, avec du travail

    Un Faker<T> se définit une fois et se réutilise d'un test à l'autre, exactement comme un générateur JustDummies.

  • AutoFixturePossible, avec du travail

    Une ICustomization rassemble un jeu de règles écrit une seule fois, dans une classe à part, et chaque test qui l'active en hérite.

  • Valeur en durPossible, avec du travail

    Une valeur peut être extraite dans une constante nommée ou un helper, puis partagée. Vous la maintenez alors à la main, et tous les tests qui la partagent tournent sur la même valeur.

De quelle nature de valeur ai-je besoin ?

Des données vraisemblables

Cette valeur sera-t-elle lue par un humain, ou seulement par une assertion ?

Valide et vraisemblable ne sont pas la même chose. Une référence qui respecte toutes les règles peut très bien ressembler à du bruit. C'est sans importance dans une assertion, et gênant dans une capture d'écran.

Terme technique : fausses données — la famille des bibliothèques faker

  • JustDummiesCe n'est pas son rôle

    Valides, pas vraisemblables. Il n'y a ici aucun catalogue de noms, d'adresses ou d'e-mails.

  • BogusConçu pour ça
  • AutoFixtureCe n'est pas son rôle

    Les valeurs sont anonymes par conception — une chaîne, c'est un nom de propriété suivi d'un GUID. Ressembler à du réel n'est pas ce qu'AutoFixture cherche à faire.

  • Valeur en durPossible, avec du travail

    Aussi vraisemblable que la valeur que vous tapez : marie.durand@acme.fr l'est autant qu'une valeur générée. Il faut la retaper au test suivant.

Chercher la valeur qui casse votre code

Est-ce que je veux une valeur quelconque, ou des centaines à la recherche d'un contre-exemple ?

Une valeur tirée par exécution vous dit que le code a tenu pour cette valeur-là. L'approche inverse exécute la même assertion sur des centaines d'entrées générées, puis réduit tout échec à la plus petite entrée qui échoue encore.

Terme technique : property-based testing, et shrinking

  • JustDummiesCe n'est pas son rôle

    Chaque exécution tire une valeur, et vous pouvez la tirer de nouveau à l'identique. Il n'y a pas de balayage systématique à la recherche de l'entrée qui échoue.

  • BogusCe n'est pas son rôle

    Bogus remplit des valeurs. Il n'exécute pas votre test en boucle pour en trouver une qui échoue.

  • AutoFixtureCe n'est pas son rôle

    Une valeur anonyme par demande, pas une recherche de celle qui met votre code en défaut.

  • Valeur en durCe n'est pas son rôle

    Une valeur, choisie une fois, et la même pour toute la vie du test.

Aucune des quatre options ne le fait. En .NET, on se tourne d'ordinaire vers FsCheck ou CsCheck, et ils cohabitent avec n'importe laquelle d'entre elles plutôt que de la remplacer.

Que se passe-t-il quand ça casse, et qui écrit la préparation ?

Rejouer l'exécution qui a échoué

La CI est passée au rouge sur une valeur tirée. Puis-je récupérer exactement cette valeur ?

Des valeurs qui changent à chaque exécution, c'est un test qui peut échouer aujourd'hui et passer demain. Ce qui rend la chose vivable, c'est un numéro que l'exécution en échec rapporte, et qui retire exactement les mêmes valeurs quand vous le recollez.

Terme technique : seed

  • JustDummiesConçu pour ça

    Un cas de test qui échoue rapporte son seed, et ce seed retire exactement les mêmes valeurs. Chaque cas tire le sien : une suite qui tourne en parallèle vous rend donc bien celui du cas qui a échoué. C'est l'adaptateur xUnit qui le fournit ; il n'existe aujourd'hui ni adaptateur NUnit ni adaptateur MSTest.

  • BogusConçu pour ça

    UseSeed sur un Faker, ou Randomizer.Seed pour toute l'exécution, rend un tirage rejouable.

  • AutoFixtureCe n'est pas son rôle

    Il n'y a pas de seed à fixer : une exécution ne se rejoue pas valeur pour valeur. C'est un manque, pas une décision — le tirage aléatoire rejouable est une demande encore ouverte chez le projet, déposée en septembre 2023.

  • Valeur en durConçu pour ça

    La même valeur à chaque exécution, puisque c'est celle que vous avez tapée. Rien à rejouer, et rien qui varie.

Détecté avant même de lancer le test

Est-ce que je l'apprends dans l'éditeur, ou dix minutes plus tard ?

Une chaîne de contraintes peut se contredire : trois caractères au plus, et commençant par ORD-. Rien ne satisfait les deux. La question est de savoir si cela apparaît comme une erreur de compilation, ou comme une exception à la première exécution.

Terme technique : analyseur Roslyn

  • JustDummiesConçu pour ça

    Les analyseurs sont livrés gratuitement dans le paquet principal, sans palier payant : installer la bibliothèque les installe. Ils détectent immédiatement, dans l'éditeur, une contrainte contradictoire — par exemple trois caractères au plus, et devant commencer par ORD-. Ce qui reste hors de portée ici, c'est un invariant métier que personne n'a déclaré comme règle : il vit dans le code ordinaire d'un constructeur, sans liste structurée des invariants d'un type à laquelle un analyseur pourrait le confronter. C'est plus étroit qu'il n'y paraît : l'analyseur de Bogus Premium peut signaler une propriété sans RuleFor, parce que les propriétés d'un Faker<T> forment un ensemble connu et énumérable. Les invariants d'un constructeur écrit à la main ne le sont pas.

  • BogusPossible, avec du travail

    Le paquet gratuit détecte une règle manquante à l'exécution : StrictMode(true) fait échouer Generate, et AssertConfigurationIsValid le vérifie à la demande. La détecter pendant que vous tapez, c'est l'analyseur de Bogus Premium, qui relève d'une licence payante.

  • AutoFixtureCe n'est pas son rôle

    Aucun analyseur n'est livré avec. Une configuration incapable de produire une valeur se découvre à l'exécution du test.

  • Valeur en durCe n'est pas son rôle

    Le compilateur accepte toute valeur du bon type — une chaîne trop longue, par exemple. Seul le constructeur du domaine l'arrête, à l'exécution.

Un outil qui écrit la préparation pour vous

Dois-je écrire à la main un builder pour chacun de mes quarante types du domaine ?

Les contraintes d'une commande, c'est un fichier que quelqu'un doit écrire, puis réécrire le jour où le type gagne un paramètre. La question est de savoir si un outil lit vos propres sources et l'écrit. Ce qu'il écrit est du C# ordinaire, dans votre projet de test : vous le lisez, vous le modifiez, vous le committez.

Terme technique : scaffolding — et non un générateur de source, qui tourne à la compilation et ne vous laisse aucun fichier

  • JustDummiesConçu pour ça

    L'outil dum lit votre type et écrit le générateur dans votre projet de test. Le fichier est du C# ordinaire, et il vous appartient : à vous de le modifier et de le committer.

  • BogusPossible, avec du travail

    Le même analyseur Premium propose la règle manquante sous forme de correctif en un clic dans l'éditeur. C'est une aide d'une autre nature qu'un fichier écrit par un outil et que vous gardez.

  • AutoFixtureCe n'est pas son rôle

    Rien n'écrit de fichier à votre place, et c'est l'inverse qui est visé : sans règle à déclarer, il n'y a pas de code de préparation à écrire.

  • Valeur en durCe n'est pas son rôle

    Vous la tapez. Il n'y a rien à générer.

Quand un autre outil est la bonne réponse

Trois cas où l'une des autres options est le bon choix.

Bogus

Choisissez Bogus quand les données doivent être vraisemblables : noms, adresses, e-mails, une base de démonstration que quelqu'un va lire. Son catalogue est adapté à la locale, un travail que vous feriez sinon à la main. JustDummies tire des valeurs valides, pas des valeurs crédibles.

AutoFixture

Choisissez AutoFixture quand le test a besoin d'un objet entier et n'a rien à dire de son contenu. Un appel remplit l'objet et tout ce qu'il contient, y compris les types dont vous n'avez pas le code. JustDummies, lui, part des règles : là où il n'y a aucune règle à énoncer, il ajoute une étape et n'apporte rien.

Valeur en dur

Écrivez la valeur en clair quand elle est le sujet du test — le montant qu'une assertion compare, le statut dont dépend un comportement. Le lecteur voit la valeur exacte sur la ligne qui l'utilise. Une valeur tirée l'obligerait à croire sur parole qu'elle convient.

Quand ne pas utiliser JustDummies

Les cas où un autre outil, ou aucun outil, vaut mieux.

  • Les données doivent être vraisemblables.

    Une démo, une capture d'écran, une base que quelqu'un va parcourir. Prenez un générateur de fausses données. Une valeur valide n'est pas une valeur crédible.

  • Vous voulez que le test parte chercher un contre-exemple.

    Exécuter une même assertion sur des centaines d'entrées générées, puis réduire un échec à son plus petit cas, c'est du property-based testing. JustDummies tire une valeur par exécution, et ce n'est pas cet outil-là.

  • Vous avez besoin d'un mot de passe, d'un jeton ou d'une clé.

    Les générateurs produisent des valeurs de test, pas des secrets. Rien de ce qui est tiré ici n'est propre à servir d'élément d'authentification, dans un test comme ailleurs.

Essayez-le

Ajoutez le paquet à un projet de test et changez une ligne dans une seule préparation. Tous les autres tests restent tels quels. Bogus, AutoFixture, vos propres builders et toutes les valeurs que vous avez déjà écrites continuent de fonctionner, dans le même projet et dans le même fichier. S'il ne fait pas ses preuves, revenir en arrière consiste à supprimer les lignes ajoutées.

Installer la bibliothèque

dotnet add package JustDummies --prerelease

Comment ce comparatif a été vérifié

Toute affirmation portant sur un autre projet vient de sa propre documentation ou de son dépôt. Ce qui a été lu, et où, figure ci-dessous.

Dernière vérification : 16 août 2026

Bogus

Lu : le catalogue adapté à la locale (Name, Address, Internet, Commerce), RuleFor et les règles qui se chaînent sur un Faker<T> construit sur place, les tirages bornés comme Random.Int(min, max), StrictMode et AssertConfigurationIsValid, UseSeed et Randomizer.Seed, et l'offre payante Bogus Premium, dont l'analyseur signale un RuleFor manquant et sait l'insérer.

AutoFixture

Lu : des valeurs anonymes plutôt que réalistes, la construction automatique de valeurs de presque n'importe quel type, la prise en compte des annotations [Range], [StringLength] et [RegularExpression] sans configuration, la surcharge Build<T>().With(...), la voie séparée ISpecimenBuilder et Customize<T>(), et la demande toujours ouverte d'un tirage aléatoire rejouable.

Cités sans être comparés

Les deux bibliothèques de property-based testing vers lesquelles cette page renvoie, pour le seul critère auquel aucune des quatre options ne répond. Toutes deux ont été lues pour confirmer qu'elles font bien ce que la page en dit.

Si vous maintenez l'un de ces projets et que cette page le décrit mal, une issue est le moyen le plus rapide d'obtenir une correction. Ouvrir une issue ouvre un nouvel onglet