Having Fun with Automated Tests

You read the title right. It has the words “Fun” and “Automated Tests” in one sentence.

Consider the following test data:

_dbContext.Members.Add(new Member
{
    Id = new Guid(CONST_MEMBER_ID_1),
    FirstName = "John",
    LastName = "Smith",
    Address = "One Fictional Way",
    CellNo = "09150001111",
    Email = "johnsmith@mail.com"
});

This adds a test data to the Members table in a SQLite database using Entity Framework. This SQLite db gets created and then destroyed (using EF Migration) when I run my tests. So far all is very straightforward, no biggie.

But what if I have to generate several members into the database? Writing my own randomizer would be fun but I got some other shit to do.

Fun Factor #1: BOGUS

Let’s take a look at the very cool open source library Bogus.

From its GitHub page:

Bogus is a simple and sane fake data generator for .NET languages like C#, F# and VB.NET. Bogus is fundamentally a C# port of faker.js and inspired by FluentValidation‘s syntax sugar.

With this tool I can generate random stuff for just about everything. Names, phone numbers, email, dates. You name it.

If I needed to generate a new firstname, lastname, and email, then I would do it like this:

var names = new Bogus.DataSets.Name();
_member.FirstName = names.FirstName();
_member.LastName = names.LastName();
var internet = new Bogus.DataSets.Internet();
_member.Email = internet.Email(_member.FirstName, _member.LastName);

Perfect! More time for me to do other shit later.

Fun Factor #2: Builder Pattern

Everybody knows or have heard about the Builder design pattern. Right?

Its a design pattern popularized by the Gang of Four (GoF). The easiest example I can think of is the StringBuilder in .NET.

Well, to make testing more fun, you could take this pattern and use it to generate our test data!

I created a MemberBuilder class that will ultimately build a *surprise* Member object.

class MemberBuilder
    {
        private Member _member;
        private readonly Faker<Member> _faker;
 
        public MemberBuilder()
        {
            _faker = new Faker<Member>()
                .RuleFor(m => m.FirstName, (f, u) => f.Name.FirstName())
                .RuleFor(m => m.LastName, (f, u) => f.Name.LastName())
                .RuleFor(m => m.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName))
                .RuleFor(m => m.MembershipNo, f => f.UniqueIndex.ToString().PadLeft(5))
                .RuleFor(m => m.CellNo, f => f.Phone.PhoneNumber())
                ;
        }
 
        public Member Build()
        {
            return this._member;
        }
 
        public MemberBuilder RandomValidData()
        {
            _member = _faker.Generate();
            return this;
        }
    }

To use it:

var member = new MemberBuilder()
    .RandomValidData()
    .Build();
_dbContext.Members.Add(member);

 

Why bother?

Well, Mr Smarty Pants, I believe this form is more readable.

The above code shows me immediately that it just generated a member with random data that will be valid for all tests.

In the future when I need to test for invalid data, I could just create another RandonInvalidData() that will do exactly that.

Plus we are software engineers, we love to complicate simple stuff.

 

Published by jfaquinojr

C# and VueJS Fanboy

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: