Rails

Fake it!


Fake It!

A couple of tools to generate fake data in your app.

Hi, this time I want to talk about a couple of tools to generate fake data for your app. It is not my intention to dig deep into the controversy of data generators versus creating unique values using sequences, maybe we can leave that for another post, as of today I'd like to show you how to work with fake data.

The first one to review is the gem Forgery. Using Forgery is pretty straightforward:

If you want to give at try in your irb console:

$ gem install forgery

and require it on the console:

irb(main):004:0> require 'forgery'

you can now play with it:

irb(main):005:0> Forgery(:basic).password
=> "XsTWTcFIuLG"

If you prefer, you can also write it like this:

# instead of: Forgery(:basic).password
# try with:   Forgery::Basic.password

# instead of: Forgery(:name).full_name
# try with:   Forgery::Name.full_name   
…

If you want to use Forgery in your app, you just need to add it to your Gemfile

gem 'forgery', '0.5.0'

One of the coolest things about forgery is that you can write your own dictionaries and formats. This is accomplished by overriding or adding entries to the default dictionaries in the gem.

Once you have installed the gem in your Rails App, run this command:

$ [bundle exec] rails generate forgery
…
Creating directories in /lib/forgery...

This will generete a series of directories inside '/lib/forgery'. These directories are the ones where you will add your custom forgeries (dictionaries, class extensions, formats).

/lib/forgery/dictionaries
/lib/forgery/extensions
/lib/forgery/forgeries
/lib/forgery/formats

Let's say that we want to add a new Forgery class i.e Forgery::Pet.pet_name, first thing we need to do it's to create a pet.rb file inside /lib/forgery/forgeries and write the new class we want to add:

class Forgery::Pet < Forgery
  def self.pet_name
    dictionaries[:pet_names].random.unextend
  end
end

Next we need to add the new dictionary file pet_names (no extension) inside /lib/forgery/dictionaries in this file we are creating the list of pet names:

Jagger
Suri
Chicken
Max
Ruby

And that's it, now you can use it like any other Forgery class:

Forgery::Pet.pet_name

Another popular tool for fake data generation is the gem Faker. Faker is "a port of Perl's Data::Faker library that generates fake data.", according to their creators.

The usage of this gem is pretty similar to the previous one, for example, if we want to try it on a console, just run:

$ gem install faker

Next open your irb console and try it out:

irb(main):004:0> require 'faker'

irb(main):005:0> Faker::Name.name
=> "Jameson Jewess MD"

To use it in your app, just add it to your Gemfile and run Bundle:

gem 'faker'

The customization in Faker is not as straightforward as in Forgery, and the documentation doesn't help much, after playing with the gem for a while I finally made it work.

Faker uses the i18n locals translations, with that in mind, let's say that you want to customize an existing dictionary, i.e you want to change the state abbreviations for the address dictionary.

To accomplish this, you need to create a new file in your locals folder like this: /config/locals/custom_abbr.yml (you can use your default en.yml local file).

en:
  faker:
    address:
      state_abbr: [CAL, FLO, TEX]

And use the new definitions as usual:

irb(main):001:0> Faker::Address.state_abbr
=> "TEX"

In another example, let's say that you need to create a completely new custom class, not included in the Faker gem, city abbreviations for example. So, for this you'll need to define your new class, I called mine address_extended and defined it in a new lib file with the Faker namespace, lib/faker/ in this file we are going to define our class method:

class Faker::AddressExtended < Faker::Base
  def self.city_abbr
    fetch('address_extended.city_abbr')
  end
end

You will need to require this file in a initializers/faker.rb file

require 'faker/address_extended'

And last but not least, add your custom yml translations:

en:
  faker:
    address_extended:
      city_abbr: [LIX, NYC, SFO]

Now you can use your new Faker class:

irb(main):001:0> Faker::AddressExtended.city_abbr
=> "SFO"

So there you go, two good tools to generate fake data into your app. Keep in touch because in the next post I would like to discuss about the performance of this two gems, including ffaker, which includes the functionality of Faker and adds more to it, and also works a little bit faster.

Remember to post your comments and experiences!!

Happy Faking!

Best Practices
De Código, Café y Cervezas 07 – ¿Somos profesionales?
Quality Assurance
What really is Automation Testing?
Community
De Código, Café y Cervezas 06 – ActiveModel::Serializer