Laravel入門 テストファーストでのステータス別タブ作成とテスト(第16回)

2021-01-01
4 min read

ToDo 一覧画面のリスト表示をスタータス別の表示にします。

画面レイアウトと仕様

タスク一覧画面にスタータス別のタブを設けて表示します。

tasklistタブ

各タブの仕様は下記になります。

イベント URL 備考
未着手 /tabindex/1 get
着手中 /tabindex/2 get
完了 /tabindex/3 get
延期 /tabindex/4 get

タブをクリックすることで、該当のスタータスのタスク一覧を表示します。

テストケースとテストコード実装

考えられる大まかなテストケースとしては下記になります。

  • ステータスが未着手の一覧が表示されること
  • ステータスが着手中の一覧が表示されること
  • ステータスが完了の一覧が表示されること
  • ステータスが延期の一覧が表示されること

ブラウザテスト

上記テストケースをコーディングする前にテストケースクラスを作成します。

php artisan make:test TaskTabChangeTest

生成後にuse RefreshDatabaseなど必要なものを追記します。

ステータスが未着手の一覧が表示されること

ステータスが未着手のものを 5 件、そのほかのステータスのものを 1 件ずつデータベースに登録します。 そのうえで、未着手のものが 5 件表示されることを確認します。

public function testReadyListOnly()
{

    factory(Task::class,5)->state('Ready')->create();
    factory(Task::class,1)->state('Doing')->create();
    factory(Task::class,1)->state('Done')->create();
    factory(Task::class,1)->state('notReady')->create();


    $response = $this->get(route('tasklist',['tabindex' => 1]));
    $response->assertStatus(200);
    $response->assertViewHas('tasks');
    $tasks = $response->original['tasks'];
    $this->assertEquals(5, count($tasks));

}

ステータスが着手中の一覧が表示されること

ステータスが着手中のものを 5 件、そのほかのステータスのものを 1 件ずつデータベースに登録します。 そのうえで、着手中のものが 5 件表示されることを確認します。

public function testReadyDoingOnly()
{

    factory(Task::class,1)->state('Ready')->create();
    factory(Task::class,5)->state('Doing')->create();
    factory(Task::class,1)->state('Done')->create();
    factory(Task::class,1)->state('notReady')->create();


    $response = $this->get(route('tasklist',['tabindex' => 2]));
    $response->assertStatus(200);
    $response->assertViewHas('tasks');
    $tasks = $response->original['tasks'];
    $this->assertEquals(5, count($tasks));

}

ステータスが完了の一覧が表示されること

ステータスが完了のものを 5 件、そのほかのステータスのものを 1 件ずつデータベースに登録します。 そのうえで、完了のものが 5 件表示されることを確認します。

public function testReadyDoneOnly()
{

    factory(Task::class,1)->state('Ready')->create();
    factory(Task::class,1)->state('Doing')->create();
    factory(Task::class,5)->state('Done')->create();
    factory(Task::class,1)->state('notReady')->create();


    $response = $this->get(route('tasklist',['tabindex' => 3]));
    $response->assertStatus(200);
    $response->assertViewHas('tasks');
    $tasks = $response->original['tasks'];
    $this->assertEquals(5, count($tasks));

}

ステータスが延期の一覧が表示されること

ステータスが延期のものを 5 件、そのほかのステータスのものを 1 件ずつデータベースに登録します。 そのうえで、延期のものが 5 件表示されることを確認します。

public function testReadynotReadyOnly()
{

    factory(Task::class,1)->state('Ready')->create();
    factory(Task::class,1)->state('Doing')->create();
    factory(Task::class,1)->state('Done')->create();
    factory(Task::class,5)->state('notReady')->create();


    $response = $this->get(route('tasklist',['status' =>4]));
    $response->assertStatus(200);
    $response->assertViewHas('tasks');
    $tasks = $response->original['tasks'];
    $this->assertEquals(5, count($tasks));

}

テスト実施

テストを実施します。

$ ./vendor/bin/phpunit tests/Feature/TaskTabChangeTest.php --testdox

テストはすべてエラーになることを確認します。 テストコードに間違いがある場合は修正します。

実装

router

web.phpに、ルートを追加します。 全部で URL が 4 種類ありますが1種類にまとめます。 URLを/tabindex/{tabindex}とすることでひとつにまとめることができます。 {tabindex}には、未着手、着手中、完了、延期のステータスのコード値が入ります。

Route::get('/tabindex/{tabindex}', 'TaskController@index')->where('tabindex', '[1-4]')->name('tasklist');

whereにて、statusの値を1から4の整数に限定しています。それ以外の値が指定された場合はエラーとして取り扱われます。

コントローラ

TaskControllerindexを修正します。

スタータス別のタスク一覧を取得するようにwhereで条件をつけています。

public function index($tabindex = '1')
{
    $tasks = Task::where("status",$tabindex)->get();
    return view('index', compact('tasks','tabindex'));

}

indexメソッドの呼び出し時にステータスが省力された場合は、「1」を設定するようにしています。 また、画面にtasklistとともにtabindexを渡しています。

画面

スタータス別にタブを前面に表示するためtab-header.blade.phpを修正します。

@section('tab-header')
<div>
 <ul class="nav nav-tabs card-header-tabs">
      <li class="nav-item">
          <a class="nav-link {{ ($tabindex ?? "" ) == 1 ? 'active':''  }}" name="tab-ready" href="{{ route('tasklist',['tabindex' => 1]) }}">未着手</a>
      </li>
      <li class="nav-item">
          <a class="nav-link {{ ($tabindex ?? "" ) == 2 ? 'active':''  }}" name="tab-doing" href="{{ route('tasklist',['tabindex' => 2]) }}">着手中</a>
      </li>
      <li class="nav-item">
          <a class="nav-link {{ ($tabindex ?? "" ) == 3 ? 'active':''  }}" name="tab-done" href="{{ route('tasklist',['tabindex' => 3]) }}">完了</a>
      </li>
      <li class="nav-item">
          <a class="nav-link {{ ($tabindex ?? "" ) == 4 ? 'active':''  }}" name="tab-notready" href="{{ route('tasklist',['tabindex' => 4]) }}" >延期</a>
      </li>
  </ul>
  </div>
@endsection

($tabindex ?? "" ) == 1 ? 'active':''は、三項式で条件が満たされた場合、activeという CSS クラスを付与します。

テスト

テストを実施します。

$ php artisan test tests/Feature/TaskTabChangeTest.php --testdox
PHPUnit 8.5.8 by Sebastian Bergmann and contributors.

Task Tab Change (Tests\Feature\TaskTabChange)
 ✔ Ready list only
 ✔ Ready doing only
 ✔ Ready done only
 ✔ Readynot ready only

Time: 2.53 seconds, Memory: 34.01 MB

完成です。