Bogus – generowanie danych testowych

Generowanie danych testowych

W jednym z wcześniejszych wpisów pokazałem, jak za pomocą dwóch bibliotek (Nbuilder oraz Faker.NET) wygenerować dane testowe. Przez dłuższy czas korzystałem z tamtego rozwiązania, natomiast ostatnio kolega z pracy pokazał mi inną, ciekawszą bibliotekę, która łączy działanie Nbuildera oraz Faker.NET. Do tego ma kilka dodatkowych funkcji, które się przydają. Biblioteka nazywa się Bogus (strona projektu) i jest to port biblioteki Faker.js.

Po pierwsze – biblioteka umożliwia wygenerowanie jednego lub wielu obiektów, gdzie dane, podobnie jak w Faker.NET, wyglądają na realne (nie są to generyczne wartości na podstawie nazwy właściwości, jak to się dzieje w Nbuilder).

Po drugie – autor biblioteki wzorował się na bibliotece FluentValidation, więc sposób pracy z Bogus jest bardzo podobny, co bardzo przypadło mi do gustu, jako że jestem wielkim fanem FluentValidation.

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 30 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Bogus

Myślę, że najlepiej przejść od razu do dema i zobaczyć, jak wygląda biblioteka w praktyce. Cały przykład jest dostępny na githubie, więc możesz go ściągnąć i samemu sprawdzić, jak działa Bogus.

Na potrzeby przykładu przygotowałem trzy klasy, które wypełnimy danymi: User, Product oraz Order. Klasa reprezentująca zamówienia będzie korzystać z klasy użytkownika oraz produktu. Klasy wyglądają tak:

public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Gender Gender { get; set; }
}
public enum Gender
{
Male = 0,
Female = 1
}
public class Product
{
public string Name { get; set; }
public string Company { get; set; }
public decimal Price { get; set; }
}
public class Order
{
public DateTime Date { get; set; }
public User User { get; set; }
public Product Product { get; set; }
public int Count { get; set; }
public OrderStatus Status { get; set; }
}
public enum OrderStatus
{
New,
Processing,
Completed,
Canceled
}
view raw Models.cs hosted with ❤ by GitHub

Samo skorzystanie z biblioteki Bogus jest dość proste. Wystarczy utworzyć instancję generycznej klasy Faker, w której jako parametr przekazujemy typ, który będziemy wypełniać danymi. Następnie za pomocą metody RuleFor konfigurujemy sposób generowania danych. Samo utworzenie obiektu lub obiektów wykonuje się przez wywołanie metody Generate (gdy jako parametr przekażemy liczbę, wtedy dostaniemy kolekcję obiektów zamiast jednego obiektu). Poniżej przykład generowania listy 10 użytkowników:

var users = new Faker<User>(locale)
.StrictMode(true)
.RuleFor(u => u.Gender, (f, u) => f.PickRandom<Gender>())
.RuleFor(u => u.FirstName, (f, u) => f.Name.FirstName((Bogus.DataSets.Name.Gender)u.Gender))
.RuleFor(u => u.LastName, (f, u) => f.Name.FirstName((Bogus.DataSets.Name.Gender)u.Gender))
.RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName))
.Generate(10);
view raw Program1.cs hosted with ❤ by GitHub

Jak widać powyżej, użycie biblioteki jest relatywnie proste. Co fajne, część danych może zależeć od innych danych. Na przykład imię oraz nazwisko mogą zależeć od płci użytkownika (tutaj jedyny minus dotyczący tego, że musimy przekazać wartość enuma Gender z biblioteki Bogus), czy w przypadku takich danych jak adres e-mail lub nazwa użytkownika możemy bazować na imieniu oraz nazwisku. Dzięki temu możemy uzyskać dane w stylu: Anne.Marsha78@yahoo.com dla imienia Anne oraz nazwiska Marsha. Takie działanie biblioteki powoduje, że dane są jeszcze bardziej realne.

Ciekawą opcją jest jeszcze ustawienie StrictMode na true (domyślnie ma wartość false, można to skonfigurować globalnie dla całej aplikacji). Ustawienie to wymusi określenie ról generowania danych dla wszystkich właściwości obiektu.

Poniżej znajduje się kod generujący dane dla pozostałych dwóch klas (Product oraz Order).

var products = new Faker<Product>(locale)
.StrictMode(true)
.RuleFor(p => p.Name, (f, p) => f.Commerce.ProductName())
.RuleFor(p => p.Company, (f, p) => f.Company.CompanyName())
.RuleFor(p => p.Price, (f, p) => f.Random.Decimal(0.01M, 1000M))
.Generate(10);
var orders = new Faker<Order>(locale)
.StrictMode(true)
.RuleFor(o => o.User, (f, p) => f.PickRandom(users))
.RuleFor(o => o.Product, (f, p) => f.PickRandom(products))
.RuleFor(o => o.Count, (f, p) => f.Random.Int(1, 20))
.RuleFor(o => o.Date, (f, p) => f.Date.Past(2))
.RuleFor(o => o.Status, (f, p) => f.PickRandom<OrderStatus>())
.Generate(100);
view raw Program2.cs hosted with ❤ by GitHub

Jak widać między innymi w powyższym kodzie, liczba typów danych dostępnych w bibliotece Bogus jest bardzo duża. Co ciekawe, możemy też używać wcześniej wygenerowanych danych – tak jak w przypadku obiektu użytkownika oraz produktu podczas generowania zamówień. Można w prosty sposób wybrać losowy obiekt z już istniejącej kolekcji.

Kolejną fajną funkcjonalnością biblioteki jest wsparcie dla lokalizowania wygenerowanych danych. Wspieranych jest kilkadziesiąt języków, w tym i język polski. Niestety w przypadku naszego języka część wygenerowanych danych jest w języku polskim, a część w angielskim, co wygląda dość dziwnie:

Bogus wynik danych testowych

Sama zmiana języka generowania danych jest dość prosta. Najłatwiej stworzyć zmienną z kodem języka i później przekazywać ją w konstruktorze do klasy Faker:

string locale = "pl";
var users = new Faker<User>(locale)
.Generate(10);
view raw Program3.cs hosted with ❤ by GitHub

Podsumowanie

Mam nadzieję, że biblioteka Bogus spodobała Ci się i będziesz jej używał w swoich projektach. Tak jak zaznaczam to w innych wpisach, cały kod znajduje się na githubie.

A może Ty znasz jakąś inną bibliotekę tego typu? Jeśli tak, to daj mi znać, z chęcią ją poznam. 🙂

3 thoughts on “Bogus – generowanie danych testowych

  • Pingback: dotnetomaniak.pl
    • Wcześniej również wykorzystywałem Nbuilder (tylko, że w połączeniu do Faker.NET – https://plawgo.pl/2018/03/02/nbuilder-oraz-faker-net-generowanie-danych/) ale Bogus generuje dużo fajniejsze dane (w szczególności możliwość bazowania na innych właściwościach). Więc Nbuilder został tylko do generowania danych w testach jednostkowych, bo tam Bogus się nie sprawdza.

      Co do składni Rules – sprawdzałem i jakoś bardziej lubie z RuleFor, ale to prawdopodobnie wynika głównie z tego, że od lat używam Fluent Validation, więc ta składnia jest dla mnie jakoś bardziej normalna 🙂

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.