-
-
Save adamwathan/dd46a8501097942a771925c02bac0111 to your computer and use it in GitHub Desktop.
<?php | |
use Illuminate\Contracts\Console\Kernel; | |
trait DatabaseSetup | |
{ | |
protected static $migrated = false; | |
public function setupDatabase() | |
{ | |
if ($this->isInMemory()) { | |
$this->setupInMemoryDatabase(); | |
} else { | |
$this->setupTestDatabase(); | |
} | |
} | |
protected function isInMemory() | |
{ | |
return config('database.connections')[config('database.default')]['database'] == ':memory:'; | |
} | |
protected function setupInMemoryDatabase() | |
{ | |
$this->artisan('migrate'); | |
$this->app[Kernel::class]->setArtisan(null); | |
} | |
protected function setupTestDatabase() | |
{ | |
if (! static::$migrated) { | |
$this->artisan('migrate:refresh'); | |
$this->app[Kernel::class]->setArtisan(null); | |
static::$migrated = true; | |
} | |
$this->beginDatabaseTransaction(); | |
} | |
public function beginDatabaseTransaction() | |
{ | |
$database = $this->app->make('db'); | |
foreach ($this->connectionsToTransact() as $name) { | |
$database->connection($name)->beginTransaction(); | |
} | |
$this->beforeApplicationDestroyed(function () use ($database) { | |
foreach ($this->connectionsToTransact() as $name) { | |
$database->connection($name)->rollBack(); | |
} | |
}); | |
} | |
protected function connectionsToTransact() | |
{ | |
return property_exists($this, 'connectionsToTransact') | |
? $this->connectionsToTransact : [null]; | |
} | |
} |
<?php | |
abstract class TestCase extends Illuminate\Foundation\Testing\TestCase | |
{ | |
use DatabaseSetup; | |
/** | |
* The base URL to use while testing the application. | |
* | |
* @var string | |
*/ | |
protected $baseUrl = 'http://localhost'; | |
protected function setUp() | |
{ | |
parent::setUp(); | |
$this->setupDatabase(); | |
} | |
/** | |
* Creates the application. | |
* | |
* @return \Illuminate\Foundation\Application | |
*/ | |
public function createApplication() | |
{ | |
$app = require __DIR__.'/../bootstrap/app.php'; | |
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); | |
return $app; | |
} | |
} |
@adamwathan Would it be better to only run refresh if migrations actually change?
Something like this?
https://gist.github.com/slava-vishnyakov/2ae1d1e030204ad10c1898b20aeba4cb#file-databasesetup-php-L33-L36
https://gist.github.com/slava-vishnyakov/2ae1d1e030204ad10c1898b20aeba4cb#file-databasesetup-php-L61-L77
https://gist.github.com/slava-vishnyakov/2ae1d1e030204ad10c1898b20aeba4cb/revisions?diff=split
For my app refresh
takes 3.5 seconds :( So this really speeds up the process.
@adamwathan For learning purposes, can I ask what the technical reason is for $this->app[Kernel::class]->setArtisan(null);
?
Note that Laravel has a build in trait \Illuminate\Foundation\Testing\RefreshDatabase
(formerly added as FreshDatabase) that has the same logic
Yeah, looks like it's not needed anymore in recent Laravel versions.
awesome
You should PR this into Laravel core somehow!