#native_company# #native_desc#
#native_cta#

Programmatically Create Sample Testing Data in PHP

By Voja Janjic
on June 30, 2016

Since quality assurance takes a significant amount of project time and resources, we are always looking for ways to improve its efficiency. One testing process improvement is to programmatically create sample testing data. To achieve this, we will use a popular PHP library called Faker.

Setup

Faker can be installed through Composer package manager:

composer require fzaninotto/faker

After that, create an instance of the class:

// Autoload the class
require_once '/path/to/Faker/src/autoload.php';

// Create an object
$faker = FakerFactory::create();

Now you can call class methods and each of them would return a random value of a certain type (such as a name, address, text, date and time, phone number, etc.) that you can use to populate the database. Some of the most useful ones are shown below:

// Random number with 5 digits
$faker->randomNumber(5);

// Pick a random element from a custom defined list
$faker->randomElement(array('a','b','c'));

// Address, city, postcode (U.S.) and country
$faker->streetAddress();
$faker->city();
$faker->postcode();
$faker->country();

// Geographic location
$faker->latitude();
$faker->longitude();

// Phone number and e-mail address
$faker->phoneNumber();
$faker->email();

// Generate random name
$faker->firstName();
$faker->firstNameMale();
$faker->firstNameFemale();
$faker->lastName();

// Random login details
$faker->userName();
$faker->password();

// Random dates
// Now is the latest date that can be generated and can be set to any value
$faker->dateTimeThisMonth('now');
$faker->dateTimeThisYear('now');
$faker->dateTimeThisDecade('now');
$faker->dateTimeThisCentury('now');

// Random date between 10 years ago and now
$faker->dateTimeBetween('-10 years', 'now'); 

Note that if a method is called twice, it will generate two different values:

$username1 = $faker->userName();
$username2 = $faker->userName();

ORMs and Faker

To further automate populating the database, Faker can be integrated with ORM libraries, which are usually part of modern PHP frameworks. We will see how to use Faker with Eloquent in Laravel and Doctrine in Symfony framework.

Eloquent ORM

We will use database seeders to populate the database with a single command. First, create a class DatabaseSeeder in app/database/seeds/DatabaseSeeder.php:

<?php

class DatabaseSeeder extends Seeder {

	/**
	 * Run the database seeds.
	 *
	 * @return void
	 */
	public function run()
	{
		Eloquent::unguard();
		
		$this->call('UserSeeder');
	}

}

This is the main method which will be executed upon entering the command and it is also the place where we define which seeder classes will be loaded. It is a good practice to have one class per table. So, let’s create UserSeeder in app/database/seeds/UserSeeder.php:

<?php

class UserSeeder extends DatabaseSeeder {

	public function run() 
	{
		// Instantiate the Faker library
		$faker = FakerFactory::create();

		// We will create 100 users
		$i = 0;
		$items = array();
		for($i=0;$i<100;$i++) {
			// This is the random data for each user
			$items[$i] = array(
				'email' => $faker->email(),
				'password' => Hash::make($faker->password()),
				'name' => $faker->name(),
				'address' => $faker->streetAddress(),
				'city' => $faker->city(),
				'postal_code' => $faker->postcode(),
				'lat' => $faker->latitude(),
				'lng' => $faker->longitude(),
				'phone' => $faker->phoneNumber(),
				'website' => $faker->url(),
				'is_active' => $faker->numberBetween(0,1)
			);

		}
	  
	    // We create the users by using the Eloquent model User and its built-in method
	    foreach ($items as $item) {
	      User::create($item);
	    }
	}

}

Finally, to populate the database, run the following command:

php artisan db:seed

If all went well, you should now have 100 random users in the database.

Doctrine ORM

In Symfony, the setup is a bit different, but also more automated. We will use BazingaFakerBundle, which is a bundle that integrates Faker library with Symfony. To install it, add the following to composer.json and run composer update after that:

"willdurand/faker-bundle": "@stable"

Then, we need to register the bundle in app/AppKernel.php. The file should look something like this:

public function registerBundles()
{
      // ...
      if (in_array($this->getEnvironment(), array('dev', 'test'))) {
          // ...
          $bundles[] = new BazingaBundleFakerBundleBazingaFakerBundle();
      }
}

A lot of things in Symfony are configured in YML configuration files. The same applies to this library, so we will add the following to app/config/config_dev.yml:

bazinga_faker:
    orm: doctrine
    entities:
        AppBundleEntityUser:
            number: 100

We have configured the Faker to use the Doctrine ORM, defined an entity and added the desired number of entries in the database. If we run the command to populate the database at this point, it would be successful, as the bundle will try to guess the type of each field based on your entity class. If it has guessed wrong, we can manually define which method we want to use for which field by using custom formatters:

bazinga_faker:
    orm: doctrine
    entities:
        AppBundleEntityUser:
            number: 100
            custom_formatters:
	            latitude: { method: latitude }
	            longitude: { method: longitude }

If the Faker method has one or more arguments:

bazinga_faker:
    orm: doctrine
    entities:
        AppBundleEntityUser:
            number: 100
            custom_formatters:
	            latitude: { method: latitude }
	            longitude: { method: longitude }
	            city: { method: randomElement, parameters: [ [ 'New York', 'Los Angeles', 'San Francisco', 'London', 'Paris', 'Tokyo' ] ] }

To populate the database, run the following command:

php app/console faker:populate

Next Steps

Check out the full Faker PHP library reference here, and BazingaFakerBundle here.