Laravelの ドキュメント は、テスト間でデータベースを移行およびロールバックするためにDatabaseMigrations
特性を使用することを推奨しています。
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends TestCase
{
use DatabaseMigrations;
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->get('/');
// ...
}
}
ただし、テストで使用するシードデータがいくつかあります。私が実行した場合:
php artisan migrate --seed
その後、最初のテストでは機能しますが、後続のテストでは失敗します。これは、特性が移行をロールバックし、移行を再度実行するときにデータベースをシードしないためです。移行時にデータベースシードを実行するにはどうすればよいですか?
あなたがする必要があるのは、職人の電話をかけることですdb:seed
setUp関数内
<?php
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends TestCase
{
use DatabaseMigrations;
public function setUp(): void
{
parent::setUp();
// you can call
$this->artisan('db:seed');
// or
$this->seed();
}
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->get('/');
// ...
}
}
参照: https://laravel.com/docs/5.6/testing#creating-and-running-tests
これを理解するには掘り下げたので、 共有したいと思った 。
DatabaseMigrations
trait のソースコードを見ると、1つの関数 runDatabaseMigrations
が呼び出されていることがわかります。 setUp
which すべてのテストの前に実行 そして、分解時に実行されるコールバックを登録します。
"extend" trait the trait を並べ替えることができます。そのためには、その関数のエイリアスを作成し、ロジックを含む新しい関数を再宣言します(artisan db:seed
)元の名前で、その中のエイリアスを呼び出します。
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends TestCase
{
use DatabaseMigrations {
runDatabaseMigrations as baseRunDatabaseMigrations;
}
/**
* Define hooks to migrate the database before and after each test.
*
* @return void
*/
public function runDatabaseMigrations()
{
$this->baseRunDatabaseMigrations();
$this->artisan('db:seed');
}
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->get('/');
// ...
}
}
この質問にはすでに何度か答えられていることは知っていますが、この特定の答えが見当たらないので、私はそれを投げ入れると思いました。
laravel(少なくともv5.5以降))ではしばらくの間、TestCase
クラスにデータベースシーダーの呼び出しに特に使用されるメソッドがありました。
https://laravel.com/api/5.7/Illuminate/Foundation/Testing/TestCase.html#method_seed
このメソッドでは、$this->seed('MySeederName');
を呼び出してシーダーを起動するだけです。
したがって、すべてのテストの前にこのシーダーを起動するには、次のsetUp関数をテストクラスに追加できます。
public function setUp()
{
parent::setUp();
$this->seed('MySeederName');
}
最終結果は次と同じです。
$this->artisan('db:seed',['--class' => 'MySeederName'])
または
Artisan::call('db:seed', ['--class' => 'MySeederName'])
しかし、構文は少し簡潔です(私の意見では)。
RefreshDatabase
テスト特性を使用している場合:
abstract class TestCase extends BaseTestCase
{
use CreatesApplication, RefreshDatabase {
refreshDatabase as baseRefreshDatabase;
}
public function refreshDatabase()
{
$this->baseRefreshDatabase();
// Seed the database on every database refresh.
$this->artisan('db:seed');
}
}
ArtisanのネイティブDatabaseMigrationsおよびシーダー/移行方法をバイパスする場合の代替ソリューションを次に示します。独自の特性を作成して、データベースをシードできます。
namespace App\Traits;
use App\Models\User;
use App\Models\UserType;
trait DatabaseSetup
{
public function seedDatabase()
{
$user = $this->createUser();
}
public function createUser()
{
return factory(User::class)->create([
'user_type_id' => function () {
return factory(UserType::class)->create()->id;
}
]);
}
public function getVar() {
return 'My Data';
}
}
次に、テストで次のように呼び出します。
use App\Traits\DatabaseSetup;
class MyAwesomeTest extends TestCase
{
use DatabaseSetup;
use DatabaseTransactions;
protected $reusableVar;
public function setUp()
{
parent::setUp();
$this->seedDatabase();
$this->reusableVar = $this->getVar();
}
/**
* @test
*/
public function test_if_it_is_working()
{
$anotherUser = $this->createUser();
$response = $this->get('/');
$this->seeStatusCode(200);
}
}