Paulund

Create Test Database For Unit Tests On Laravel

When you're testing your Laravel application particularly with functional tests there will be times where you need to test database interactions, such as if you testing the form posting you'll need to make sure you can also do a GET on this table to the new data back out. The problem you get is if you have this in your unit tests then you could slowly populate your dev database with all this data from your unit tests. In this tutorial, we're going to learn how you can create a database.sqlite file to use for your test database.

Create Test Database Connection

To create a new test database connection all you have to do is add a new connection to the database confile file config/database.php.


'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            'database' => database_path('database.sqlite'),
            'prefix' => '',
        ],

Testing Environment Settings

Add testing specific environment variable changes in the phpunit.xml. Here you can override any of the environment variables, were going to change - APP_ENV - Settings for environment name

  • CACHE_DRIVER - Method of caching
  • SESSION_DRIVER - Method of session
  • QUEUE_DRIVER - Method for queue
  • DB_CONNECTION - Database connection same name as testing database
  • DB_DATABASE - Method of database type

<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

Create A New Command

You can use artisan to create a new command, we're going to create one that will setup the test database sqlite file for us. Run the following command on the commandline.


php artisan make:command MakeTestDb

You'll notice there will be a new file in App\Console\Commands. Open this class and replace it with the code below.


<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\Factory;

class MakeTestDb extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'testdb:make';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Make test db';

    /**
     * @var \Illuminate\Contracts\Filesystem\Filesystem
     */
    private $fileSystem;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(Factory $storage)
    {
        parent::__construct();

        $this->fileSystem = $storage->disk('database');
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        $this->fileSystem->put('database.sqlite', '');
        $this->call('migrate', [
            '--database' => 'sqlite'
        ]);
    }
}

You can now use the command php artisan testdb:make which will create a new file called database.sqlite and run the migration command on this file. Now when you run your unit tests the data will be stored in a sqlite file and not your dev database.