まとめ
- 最初にやったのは、テストと開発環境間で影響を与えない独立した状況を作ること。 -> Laravel 5.8。インメモリの SQLite で PHPUnit テストを行う設定 – oki2a24
use RefreshDatabase;
で各テストの後にデータベースをリセットする。 -> 各テスト後のデータベースリセット データベースのテスト 5.8 Laravel- アプリの初期セットアップ状態を再現するために、
setup()
メソッド内で、$this->seed();
を呼び出す。
補足。データベースのリセットは各テストクラス内で行うことにした
Laravel 5.8 では、各テストクラスを php artisan make:test
で生成すると、 extends TestCase
しています。
したがって、この TestCase で use RefreshDatabase;
したり、 setup()
メソッドを定義して $this->seed()
してもよいです。
そうすれば、各テストクラスでこれらの記述をしなくて済みます。
ですけれども、あえて行わないことにしました。データベースをリセットしたいかどうか、シーディングをしたいかどうか、は各テストメソッド毎に異なるはずだからです。
ただ、結局は全てのテストクラスでデータベースをリセットし、さらにシーディングを行うのかもしれません。そして、 TestCase クラスで定義しておけばよかった、と修正する日が来るのかもしれません。
その時は、そうしようと思います。
コード例
例えば次のようなテスト、ファクトリでテストしました。
- ファクトリクラスが大きくなった。もっと小さくできそうだが、まだよく考えていない。
tests/Feature/Admin/PostControllerTest.php
<?php
namespace Tests\Feature\Admin;
use App\Models\Wp\Post;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PostControllerTest extends TestCase
{
use RefreshDatabase;
/**
* 各テスト実行前に呼ばれる。
*/
protected function setUp(): void
{
parent::setUp();
$this->seed();
}
/**
* @test
*
* @return void
*/
public function post_typeがpostのレコードが表示されること()
{
$post = factory(Post::class, 'post_type_post')->create();
$page = factory(Post::class, 'post_type_page')->create();
$attachment = factory(Post::class, 'post_type_attachment')->create();
$revision = factory(Post::class, 'post_type_revision')->create();
$navMenuItem = factory(Post::class, 'post_type_nav_menu_item')->create();
$response = $this->get('/admin/posts');
$response
->assertViewIs('admin.posts.index')
->assertStatus(200)
->assertSee($post->post_title)
->assertDontSee($page->post_title)
->assertDontSee($attachment->post_title)
->assertDontSee($revision->post_title)
->assertDontSee($navMenuItem->post_title);
}
/**
* @test
*
* @return void
*/
public function post_statusが適切なレコードが表示されること()
{
$publish = factory(Post::class, 'post_type_post')->create();
$future = factory(Post::class, 'post_status_future')->create();
$draft = factory(Post::class, 'post_status_draft')->create();
$pending = factory(Post::class, 'post_status_pending')->create();
$private = factory(Post::class, 'post_status_private')->create();
$trash = factory(Post::class, 'post_status_trash')->create();
$autoDraft = factory(Post::class, 'post_status_auto-draft')->create();
$inherit = factory(Post::class, 'post_status_inherit')->create();
$response = $this->get('/admin/posts');
$response
->assertViewIs('admin.posts.index')
->assertStatus(200)
->assertSee($publish->post_title)
->assertSee($future->post_title)
->assertSee($draft->post_title)
->assertSee($pending->post_title)
->assertSee($private->post_title)
->assertSee($trash->post_title)
->assertDontSee($autoDraft->post_title)
->assertDontSee($inherit->post_title);
}
/**
* @test
*
* @return void
*/
public function post_dateの降順に表示されること()
{
$posts = factory(Post::class, 'post_type_post', 3)->create();
$expects = $posts
->sortByDesc(function ($item) {
return $item->post_date;
})
->values()
->pluck('post_title')
->all();
$response = $this->get('/admin/posts');
$response
->assertViewIs('admin.posts.index')
->assertStatus(200)
->assertSeeInOrder($expects);
}
}
database/factories/PostFactory.php
<?php
/* @var $factory \Illuminate\Database\Eloquent\Factory */
use App\Models\Wp\Post;
use Faker\Generator as Faker;
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_type_post');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'page',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_type_page');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'attachment',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_type_attachment');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'revision',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_type_revision');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'nav_menu_item',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_type_nav_menu_item');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'future',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_future');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'draft',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_draft');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'pending',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_pending');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'private',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_private');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'trash',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_trash');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'auto-draft',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_auto-draft');
$factory->define(Post::class, function (Faker $faker) {
return [
'post_author' => 1,
'post_date' => $faker->dateTime,
'post_date_gmt' => $faker->dateTime,
'post_content' => $faker->realText,
'post_title' => $faker->realText(100),
'post_excerpt' => '',
'post_status' => 'inherit',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => $faker->text(100),
'to_ping' => '',
'pinged' => '',
'post_modified' => $faker->dateTime,
'post_modified_gmt' => $faker->dateTime,
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => $faker->url,
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => 0,
];
}, 'post_status_inherit');
おわりに
Laravel 5.8。インメモリの SQLite で PHPUnit テストを行う設定 – oki2a24 を行なった後、何に気をつけるといいのだっけ? 忘れてしまったよ><ということがありましたので、例を取り上げて学んだことをメモいたしました。
以上です。