Skip to content

Instantly share code, notes, and snippets.

@Alymosul
Last active April 22, 2026 18:31
Show Gist options
  • Select an option

  • Save Alymosul/c38504126f92b6c054164ca061c397a3 to your computer and use it in GitHub Desktop.

Select an option

Save Alymosul/c38504126f92b6c054164ca061c397a3 to your computer and use it in GitHub Desktop.

Revisions

  1. Alymosul revised this gist Jan 6, 2018. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -12,4 +12,7 @@ achieve that as follows
    SeedDatabaseState::$seeders = [RolesSeeder::class, PermissionSeeder::class];
    $this->seedDatabase();
    }

    Instructions:
    - Place the SeedDatabase.php and the SeedDatabaseState.php into the tests folder in your Laravel project and update the TestCase.php to use the SeedDatabase trait and make the changes in the setup() method to call $this->seedDatabase(); after calling the parent::setup()

  2. Alymosul revised this gist Jan 6, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    SeedDatabase trait along with SeedDatabaseState class gives your Laravel project the ability to seed the testing database once before running
    the full suite tests, which improves the speed of the tests if you were to seed the testing database before each test.
    the full suite tests, which improves the speed of the tests than seeding the testing database before each test.

    Also, it has the option to run custom seeders instead of the seeders that are called in the run() method of the DatabaseSeeder class you can
    achieve that as follows
  3. Alymosul created this gist Jan 6, 2018.
    15 changes: 15 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    SeedDatabase trait along with SeedDatabaseState class gives your Laravel project the ability to seed the testing database once before running
    the full suite tests, which improves the speed of the tests if you were to seed the testing database before each test.

    Also, it has the option to run custom seeders instead of the seeders that are called in the run() method of the DatabaseSeeder class you can
    achieve that as follows

    ...in the Testcase.php

    public function setUp()
    {
    parent::setUp();
    SeedDatabaseState::$seeders = [RolesSeeder::class, PermissionSeeder::class];
    $this->seedDatabase();
    }

    82 changes: 82 additions & 0 deletions SeedDatabase.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    <?php

    namespace Tests;

    use Illuminate\Database\Seeder;
    use Illuminate\Contracts\Console\Kernel;
    use Illuminate\Foundation\Testing\DatabaseTransactions;
    use Illuminate\Foundation\Testing\RefreshDatabase;

    trait SeedDatabase
    {
    /**
    * Seeds the database.
    *
    * @return void
    */
    public function seedDatabase()
    {
    if (! SeedDatabaseState::$seeded) {
    $this->runSeeders(SeedDatabaseState::$seeders);

    $this->syncTransactionTraits();

    if (SeedDatabaseState::$seedOnce) {
    SeedDatabaseState::$seeded = true;
    }
    }
    }

    /**
    * Calls specific seeders if possible.
    *
    * @param array $seeders
    */
    public function runSeeders(array $seeders)
    {
    if (empty($seeders)) {
    $this->artisan('db:seed');

    $this->app[Kernel::class]->setArtisan(null);

    return;
    }

    $this->getSeederInstance()->call($seeders);
    }

    /**
    * Persists the seed and begins a new transaction
    * where the rollback has been already registered in Transaction traits.
    *
    * @return void
    */
    public function syncTransactionTraits()
    {
    $uses = array_flip(class_uses_recursive(static::class));

    if (isset($uses[RefreshDatabase::class]) || isset($uses[DatabaseTransactions::class])) {
    $database = $this->app->make('db');

    foreach ($this->connectionsToTransact() as $name) {
    $database->connection($name)->commit();
    $database->connection($name)->beginTransaction();
    }
    }
    }

    /**
    * Builds a quick seeder instance.
    *
    * @return Seeder
    */
    private function getSeederInstance()
    {
    return
    new class() extends Seeder {
    public function run()
    {
    }
    };
    }
    }
    27 changes: 27 additions & 0 deletions SeedDatabaseState.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    <?php

    namespace Tests;

    class SeedDatabaseState
    {
    /**
    * Indicates if the test database has been seeded.
    *
    * @var bool
    */
    public static $seeded = false;

    /**
    * Indicates if the seeders should run once at the beginning of the suite.
    *
    * @var bool
    */
    public static $seedOnce = true;

    /**
    * Runs only these registered seeders instead of running all seeders.
    *
    * @var array
    */
    public static $seeders = [];
    }
    17 changes: 17 additions & 0 deletions TestCase.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    <?php

    namespace Tests;

    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

    abstract class TestCase extends BaseTestCase
    {
    use CreatesApplication, RefreshDatabase, SeedDatabase;

    public function setUp()
    {
    parent::setUp();
    $this->seedDatabase();
    }
    }