Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Utiliser Bogus avec les Xamarin.Forms

Bogus est un complément indispensable pour les tests mais aussi la création dynamique de données de design. Connaissez-vous cette extension ?

Bogus

Bogus est une bibliothèque de Brian Chavez à utiliser dans les tests automatisés pour générer automatiquement des données de test de différents types. On peut l’utiliser dans le cadre de tests NUNIT ou de tout autres outils de test. On peut même s’en servir astucieusement dans le cadre d’un développement classique pour générer des données de Design aléatoires mais crédibles par exemple.

Bogus peut être intégré aux projets NUNIT pour tester le code Xamarin.Forms d’où l’intérêt de bien le connaître et de s’en servir pour simplifier 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 ToString() :

var m = new Revue
{ Id = 42, Titre = "La réponse à tout" };
if (m.ToString() != "42 'La réponse à tout'")
    throw new Exception("Données incorrectes");

Notez que dans le test précédent, les valeurs réelles et le titre importent peu, mais seulement le fait qu’elles soient jointes dans le cadre de l’appel ToString (). Dans cet exemple, les valeurs pour Id et Titre peuvent être considérées comme des variables / valeurs anonymes, car nous ne nous en soucions pas vraiment.

Nota : les exemples sont écrits comme du code traditionnels, dans un projet de type NUnit on utiliserait des appels à Assert() pour valider les données et non un test avec levée d’exception comme ici.

Aller plus loin avec Bogus

Le test suivant utilise le package Bogus (via NuGet) et utilise sa syntaxe de façade non fluide :

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(faker.Random.Byte() )
};

mf.ToString().Dump();
if (mf.ToString() != $"{mf.Id} '{mf.Titre}'")
    throw new Exception("Données incorrectes");

Un exemple de run donnera :

234127 'Louisiana Technician withdrawal Fresh Montana calculate feed hacking'

Le fonctionnement de Tostring() est toujours bien testé mais le test ne dépend plus d’un jeu de données fixé à l’avance mais de données aléatoires ce qui en renforce la valeur.

Bogus a aussi une puissante syntaxe fluide (« fluent ») pour définir à quoi ressemblera un objet de test. Pour utiliser la version fluide une instance de Faker <T> est créée, où T représente l’objet de test à configurer et à créer, par exemple :

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();
mff.ToString().Dump();
if (mff.ToString() != $"{mff.Id} '{mff.Titre}'")
    throw new Exception("Données incorrectes");

Un exemple de run donnera :

10 'Et repellat qui cupiditate saepe non aut repellendus.'

Comparativement à la première version qui testait en dur une instance construite à la main 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 tomber sur un cas qui ne passe pas alors qu’avec des valeurs fixes uniques on peut croire que tout marche même en exécutant 100 fois un code bogué…) et d’autre part car en utilisant au mieux Bogus nous venons de créer un « moule à instance », la variable « revueFaker » dont on peut 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 et ainsi remplir des listes par exemple pour d’autres tests.

L’étendue de Bogus

Le but n’est pas ici de réécrire la documentation de Bogus de vous proposer une rapide introduction à ce package et ses multiples possibilités. Mais dans un tel cadre nous n’avons fait qu’égratigner la surface… Bogus est d’une grande richesse !

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 la 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 est utilisée ainsi que l’API Lorem, mais il y en a plein d’autres et 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 est en accord avec les 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 Xamarin, 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 faire des mises en page plus rapides et plus propres, mais cela peut aussi servir dans le cadre d’un développement tout à fait classique, les cas ne sont pas si rares que cela où la fabrication de données aléatoires peut avoir un sens.

Stay Tuned !

Références

Bogus existe sous la forme d’un paquet Nuget à intégrer dans les projets. Comme il est Open Source et gratuit on peut aussi consulter son code sur GitHub : https://github.com/bchavez/Bogus


(*) On notera que les exemples ont été réalisés sous l’indispensable LINQPAD 6 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.

blog comments powered by Disqus