There are two ways of specifying separate database for unit test in Laravel.
Step 1: Create New Test Database Connection on config/database.php as below:
return [ ... 'default' => env('DB_CONNECTION', 'db'), 'connections' => [ 'sqlite_testing_db' => [ 'driver' => 'sqlite', 'database' => storage_path().'/testing_database.sqlite', 'prefix' => '', ], /**************** OR ******************/ 'testing_db' => [ 'driver' => 'mysql', 'host' => env('TEST_DB_HOST', 'localhost'), 'database' => env('TEST_DB_DATABASE', 'forge'), 'username' => env('TEST_DB_USERNAME', 'forge'), 'password' => env('TEST_DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ], /** Production or database DB **/ 'db' => [ 'driver' => 'mysql', 'host' => env('TEST_DB_HOST', 'localhost'), 'database' => env('TEST_DB_DATABASE', 'forge'), 'username' => env('TEST_DB_USERNAME', 'forge'), 'password' => env('TEST_DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ], ], ];
Step 2: Specify the Database Credential on .env file
TEST_DB_HOST=localhost TEST_DB_DATABASE=laravel TEST_DB_USERNAME=root TEST_DB_PASSWORD=rootwdp
Step 3: Specify test db conection to be used on phpunit.xml.
<env name="DB_CONNECTION" value="testing_db"/> OR Below If you prefer sqlite <env name="DB_CONNECTION" value="sqlite_testing_db"/>
Step 4: Migrate database to this new testing database - if you choose to use Database Transaction to Rollback insertion on the table.
php artisan migrate --database=testing_db //If using sqlite touch storage/testing_database.sqlite php artisan migrate --database=sqlite_testing
Step 5: Now, the Unit test with Database Transaction looks like below:
<?php use App\User; use Illuminate\Foundation\Testing\DatabaseTransactions; class UserTest extends TestCase { use DatabaseTransactions; /** @test */ function it_test_user_can_be_saved() { factory(User::class, 2)->create(); $users = User::all(); $this->assertEquals(2, $users->count()); } } //Run Php Unit -> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php
Note: If you prefer not to use Database Transaction, you can use setup and teardown method on TestCase.php class to migrate and rollback the database as below:
<?php use Illuminate\Support\Facades\Artisan; class TestCase extends Illuminate\Foundation\Testing\TestCase { ... public function setUp() { parent::setUp(); Artisan::call('migrate'); } public function tearDown() { Artisan::call('migrate:reset'); parent::tearDown(); } }
Step 1: Create New Test Database Connection on Database/Config.php as below:
return [ ... 'default' => env('DB_CONNECTION', 'db'), 'connections' => [ 'sqlite_testing_db' => [ 'driver' => 'sqlite', 'database' => storage_path().'/testing_database.sqlite', 'prefix' => '', ], /**************** OR ******************/ 'testing_db' => [ 'driver' => 'mysql', 'host' => env('TEST_DB_HOST', 'localhost'), 'database' => env('TEST_DB_DATABASE', 'forge'), 'username' => env('TEST_DB_USERNAME', 'forge'), 'password' => env('TEST_DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ], /** Production or database DB **/ 'db' => [ 'driver' => 'mysql', 'host' => env('TEST_DB_HOST', 'localhost'), 'database' => env('TEST_DB_DATABASE', 'forge'), 'username' => env('TEST_DB_USERNAME', 'forge'), 'password' => env('TEST_DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, ], ], ];
Step 2: Create .env.testing
environment file on root
APP_ENV=testing DB_CONNECTION=testing_db //or //DB_CONNECTION=sqlite_testing_db TEST_DB_HOST=localhost TEST_DB_DATABASE=laravel TEST_DB_USERNAME=root TEST_DB_PASSWORD=rootwdp
Step 3: Load .env.testing
testing environment, and also set up PHP artisan to migrate and rollback the database on from the TestCase.php
<?php use Illuminate\Support\Facades\Artisan; class TestCase extends Illuminate\Foundation\Testing\TestCase { public function createApplication() { $app = require __DIR__.'/../bootstrap/app.php'; //Load .env.testing environment $app->loadEnvironmentFrom('.env.testing'); $app->make('Illuminate\Contracts\Console\Kernel')->bootstrap(); return $app; } public function setUp() { parent::setUp(); Artisan::call('migrate'); } public function tearDown() { Artisan::call('migrate:reset'); parent::tearDown(); } }
Step 4: Ensure file is create if sqlite database is selected to be used!
touch storage/testing_database.sqlite
Step 5: Unit Test Sample. No need to use Database Transaction as setup and teardown method calls migrate and rollback of database respectively.
<?php use App\User; class UserTest extends TestCase { /** @test */ function it_test_user_can_be_saved() { factory(User::class, 2)->create(); $users = User::all(); $this->assertEquals(2, $users->count()); } } //Run Php Unit -> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php