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