Bogus est un outil essentiel pour les tests ainsi que pour la génération dynamique de données de design. En avez-vous entendu parler ?
Bogus
Bogus est une bibliothèque développée par Brian Chavez, utilisée dans les tests automatisés pour générer automatiquement des données de test variées. Elle est compatible avec des outils de test tels que NUNIT, et peut même être utilisée dans le développement classique pour générer des données de design aléatoires mais réalistes.
Bogus peut être intégré aux projets NUNIT pour tester le code MAUI, ce qui en fait un outil précieux à maîtriser pour simplifier et améliorer l'écriture des tests.
Introduction
A titre d'exemple(*), supposons que la classe suivante soit impliquée dans un test unitaire :
public class Revue
{
public int Id { get; set; }
public string Titre { get; set; }
public string Corps { get; set; }
public int Notation { get; set; }
public DateTimeOffset Creation { get; set; }
public override string ToString()
{ return $"{Id} '{Titre}'"; }
}
Lors d'un test, une instance de Revue peut nécessiter des propriétés contenant des valeurs ayant un minimum de sens. Cela peut être fait manuellement, par exemple pour vérifier l'implémentation de la méthode ToString() :
SyntaxEditor Code Snippet
// test "à l'ancienne"
var m = new Revue
{ Id = 42, Titre = "La réponse à tout" };
Console.WriteLine(m.ToString());
var ok = (m.ToString() == "42 'La réponse à tout'");
Console.WriteLine(ok?"Données correctes":"Données incorrectes");
Notez que dans le test précédent, les valeurs réelles pour Id et Titre importent peu ; ce qui compte, c'est qu'elles soient correctement concaténées lors de l'appel à ToString(). Dans cet exemple, ces valeurs peuvent être considérées comme des variables anonymes, car leur contenu précis n'est pas pertinent pour le test.
Nota : les exemples sont écrits comme du code traditionnel. Dans un projet de type NUnit, on utiliserait des appels à Assert() pour valider les données, plutôt qu'un test utilisant la levée d'exception comme dans cet exemple.
Aller plus loin avec Bogus
Le test suivant utilise le package Bogus (via NuGet) et utilise sa syntaxe de façade non fluide :
SyntaxEditor Code Snippet
// test Bogus via le Faker
var faker = new Bogus.Faker("fr"); // défaut en français
var mf = new Revue
{
Id = faker.Random.Int(min: 0, max: (int)1e6),
Titre = faker.Random.Words(5)
};
mf.ToString().Dump();
ok = (mf.ToString() == $"{mf.Id} '{mf.Titre}'");
Console.WriteLine(ok?"Données correctes":"Données incorrectes");
Un exemple de run donnera :
827144 'scale TCP Handcrafted Frozen Chips Representative Toys'
Données correctes
Le fonctionnement de ToString() est toujours bien testé, mais le test ne dépend plus d'un jeu de données fixé à l'avance, utilisant à la place des données aléatoires, ce qui renforce sa robustesse.
Fluent Syntax
Bogus offre également une syntaxe fluide ("fluent") puissante pour définir à quoi ressemblera un objet de test. Pour utiliser cette version fluide, une instance de Faker<T>
est créée, où T
représente l'objet de test à configurer et à créer. Par exemple :
SyntaxEditor Code Snippet
// test Bogus avec syntax fluent
var revueFaker = new Bogus.Faker<Revue>()
.RuleFor(x => x.Id, f => f.Random.Number(1, 10))
.RuleFor(x => x.Titre, f => f.Lorem.Sentence());
var mff = revueFaker.Generate();
Console.WriteLine(mff.ToString());
ok = (mff.ToString() == $"{mff.Id} '{mff.Titre}'");
Console.WriteLine(ok?"Données correctes":"Données incorrectes");
Comparée à la première version qui testait en dur une instance construite manuellement, cette version utilisant Bogus et sa syntaxe fluide est bien plus intéressante. D’une part, puisque les données sont totalement aléatoires, elles renforcent la valeur du test : on peut découvrir des cas qui échouent, alors qu'avec des valeurs fixes, on pourrait croire que tout fonctionne même en exécutant 100 fois un code bogué. D’autre part, en utilisant au mieux Bogus, nous venons de créer un « moule à instance » avec la variable revueFaker
. Nous pouvons maintenant appeler à volonté la méthode Generate()
pour créer de nouveaux objets, tous différents mais répondant à des critères précis compatibles avec notre logiciel à tester, ce qui permet de remplir des listes pour d’autres tests, par exemple.
L’étendue de Bogus
Le but n’est pas ici de réécrire la documentation de Bogus, mais de vous proposer une rapide introduction à ce package et ses multiples possibilités. Dans ce cadre, nous n’avons fait qu’effleurer la surface… Bogus est d’une grande richesse ! Consultez la page GitHub de Bogus pour en apprendre plus sur ces nombreuses possibilités !
Par exemple, le premier argument de la méthode RuleFor()
permet de sélectionner la propriété de l'objet Revue, et le second argument spécifie comment la valeur de cette propriété doit être générée. Il existe une vaste gamme de types de données de test pris en charge. Dans le code précédent, l'API aléatoire ainsi que l’API Lorem ont été utilisées, mais il y en a beaucoup d’autres, toutes très pratiques !
Voici quelques exemples de types de données générées automatiquement (je laisse volontairement la liste en anglais car cela correspond aux API proposées) :
- Addresses: ZipCode, City, Country, Latitude, etc.
- Commerce: Department name, ProductName, ProductAdjective, Price, etc.
- Company: CompanyName, CatchPhrase, Bs, etc.
- Date: Past, Soon, Between, etc.
- Finance: Account number, TransactionType, Currency, CreditCardNumber, etc.
- Image URL: Random image, Animals image, Nature image, etc.
- Internet: Email, DomainName, Ipv6, Password, etc.
- Lorem: single word, Words, Sentence, Paragraphs, etc.
- Name: FirstName, LastName, etc.
- Rant: Random user review, etc.
- System: FileName, MimeType, FileExt, etc.
Les créations de valeurs peuvent aussi se faire en mode Lazy en utilisant GenerateLazy()
.
On trouve même des extensions pour Bogus capables, par exemple, de générer de vrais textes totalement insipides mais lisibles (en anglais). Ce genre d’artifice est très utile pour générer des données de design et aider à la mise en page d’une application MAUI, UWP, WPF, etc. Il ne faut donc pas sous-estimer leur valeur !
Conclusion
Connaître Bogus n’aide pas seulement à écrire de meilleurs tests, plus complets, plus réalistes, plus changeants et donc plus fiables. Cela sert aussi à fabriquer des données de design pour des mises en page plus rapides et plus propres. En outre, Bogus peut être utilisé dans le cadre d’un développement tout à fait classique. Les cas où la fabrication de données aléatoires peut avoir un sens ne sont pas si rares.
Stay Tuned !
(*) On notera que les exemples ont été réalisés sous l’indispensable LINQPAD 8 en mode « C# Program » en y ajoutant les packages nécessaires. Le code peut ainsi facilement être testé hors d’un environnement lourd. Mais il reste bien entendu possible de l’exécuter dans un projet Visual Studio. Mais testez LinqPad c'est l'adopter !