カテゴリー
Linux

【Laravel 5.8】WordPress の DB を使ってお勉強。ユニットテストを書き始めた時のノート

まとめ

補足。データベースのリセットは各テストクラス内で行うことにした

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 を行なった後、何に気をつけるといいのだっけ? 忘れてしまったよ><ということがありましたので、例を取り上げて学んだことをメモいたしました。

以上です。

コメントを残す