Dec 16, 2013
Table of contents:
An important step towards writing bulletproof code is being able to test the application with real data. Unit tests are all well and good, but you need to also put your code through full integration tests to ensure everything works correctly as a whole.
Having test data available is also really important for building out the front-end as well as doing Quality Assurance testing within the browser.
There are a couple of ways that you could create test data for your application, but to be honest, there is no reason why you shouldn’t just use Laravel’s database seeder. It can be tempting to just grab a copy of your production database and use that as test data, but it’s not worth the risk of accidentally doing something wrong.
In this tutorial I’m going to walk you through adding test data to a Laravel 4 database.
As I mentioned above, Laravel 4 ships with database seeding already to go. If you look under app/database/seeds
you will find a file called DatabaseSeeder.php
.
If you open up that file, you should see something like this:
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Eloquent::unguard();
// $this->call('UserTableSeeder');
}
}
As you can see, this class has a single run
method, which believe it or not, will be run when you issue the seed
command from Terminal.
So in the run
method, you can simply add your code to seed your database. In the sample file that ships with Laravel, you will notice that it references another file called UserTableSeeder
. Breaking your tables up into individual files will make this process a lot more manageable going forward. However, don’t feel like you need a file for each table. If you have a couple of tables that are related it would probably make more sense to group them into one file.
The Eloquent::unguard();
line is simply telling Eloquent to allow mass assignment. When seeding your database you obviously don’t have to worry about mass assignment, so it makes this process a whole lot easier if you just turn it off.
So now if you uncomment the UserTableSeeder
line, we will make that file so that we can seed the users
table.
Create a file called UserTableSeeder.php
in the same directory and copy the following boiler plate code:
class UserTableSeeder extends Seeder
{
public function run()
{
}
}
When creating test data, you really should want it to be as close to real test data as you can get it. However creating realistic test data for hundreds of test users would be a nightmare.
Faker is a PHP package that will automatically create really good test data for you for all kinds of situations. If you have a quick scan through the read me file, you will see that Faker has us covered for a wide variety of test data.
To install Faker, simply add it as a requirement to your composer.json
file:
"require-dev": {
"fzaninotto/faker": "1.3.*@dev"
}
Now that we have everything set up, adding in test data should be really easy.
Firstly I like to create my own test account so I can log in and test the front end of the application without having to register over and over again:
$user = User::create([
"username" => "philipbrown",
"first_name" => "Philip",
"last_name" => "Brown",
"email" => "name@domain.com",
"password" => "qwerty",
]);
Next we can use Faker to create some test users:
$faker = Faker\Factory::create();
for ($i = 0; $i < 100; $i++) {
$user = User::create([
"username" => $faker->userName,
"first_name" => $faker->firstName,
"last_name" => $faker->lastName,
"email" => $faker->email,
"password" => $faker->word,
]);
}
Here I’m simply creating 100 test users. As you can see, we can use Faker to generate realistic usernames, first names, last names and email addresses.
A really good tip from Phil Sturgeon is to have a configuration setting so you can vary the number of test items for you different environments.
Once you have your seeders set up, you can simply add your test data using the artisan
command from Terminal:
php artisan db:seed
By default this will run all of your seeder files. If you only want to run one in particular you can use this command:
php artisan db:seed -class=UserTableSeeder
And finally, running the migrate:refresh
command with the --seed
flag will rollback and then rerun your migrations as well as seed your database.
Seeding your database for tests and your development environment is one of those things that Laravel just takes care for us. Grabbing a copy of the production database is bad for a whole range of reasons and so using Laravel’s seeder and the Faker PHP package allows us to create as much rich test data as we need in order to put our code through it’s paces.
This post was inspired by Phil Sturgeon’s post Useful Database Seeding. Phil is currently writing a book on Building APIs You Won’t Hate which I highly recommend if you are looking to create an API for your application.
This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.