Home » Code » Seeding a Laravel 4 database

Seeding a Laravel 4 database

Posted by on December 16th, 2013

Seeding a Laravel 4 database
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.

The Laravel 4 Seeder

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:

<?php

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:

<?php

class UserTableSeeder extends Seeder {

  public function run()
  {
 
  }

}

Using Faker

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"
  },

Adding test data

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(array(
  'username' => 'philipbrown',
  'first_name' => 'Philip',
  'last_name' => 'Brown',
  'email' => 'phil@ipbrown.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(array(
    '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.

Seeding your database

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.

Conclusion

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.

To view a full listing of the tutorials in this series, click here.

Philip Brown

Hey, I'm Philip Brown, a designer and developer from Durham, England. I create websites and web based applications from the ground up. In 2011 I founded a company called Yellow Flag. If you want to find out more about me, you can follow me on Twitter or Google Plus.

Join the Culttt

Become an insider and join the Culttt

  • Pingback: Adding Bourbon and Bourbon Neat with Bower | Culttt

  • AoSiX

    Here are some tips i use :

    1. Env specific seeds.
    You can place a switch/case statment in your main seed class, to launch seeds depending of your current environment.

    switch(app()->environment()) {
    case ‘local’:
    // run local seeds
    break;

    // …..
    }

    2. Seeds in tests
    Don’t forget you can seed directly from your tests, if you extend TestCase class :

    $this->seed(); or $this->seed(‘AnyClassName’);

    I have a lot of seed class prefixed by “Test”, that i use exclusively to seed my databases during my tests :

    $this->seed(‘TestUsersSeeder’);
    $this->seed(‘TestArticlesSeeder’);

    • http://culttt.com/ Philip Brown

      Excellent, thank you for those :)

  • Tashunka Vithu

    When I use Model::create()(for example User::create()) inside seeder files it doesn’t affect DB in any way. Do you know what’s the problem with it?

  • Denn Massalitin

    Thx) Was rather helpful!

    • http://culttt.com/ Philip Brown

      Glad you found it useful Denn :)

  • Nirmal Thapa

    For seeding the database, the best way I have found is to simply commenting out tearDownAfterClass() during the test.

    Since the generated data will not be deleted after the test.

    • http://culttt.com/ Philip Brown

      Thank you, I usually use an in-memory database and then truncate and re-seed for the test.

Supported by