Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
86
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

【Laravel】フォームリクエストバリデーションのテストコード作成

はじめに

Laravelには、フォームリクエストバリデーションというものがあります。
フォームリクエストバリデーションは、簡単に言うとLaravel標準で用意されているバリデーションとは別に、
自身でバリデーションをカスタムできる機能のことです。
バリデーションのテストは、実際に画面で入力して、手動でテストすることもできますが、
数が多くなってくると大変ですし、例えば、最大文字数255文字というルールがある場合、
手打ちで255文字の文字列を打つのはなかなか大変ですし、そもそも本当に255文字入力しているのかということも分かりづらいです。
今回、そういった問題を解消するために、バリデーションのテストコードの書き方を紹介したいと思います。

環境

  • OS X El Capitan 10.11.6
  • PHP 7.0.18
  • laravel/framework 5.4.19
  • laravel/dusk 1.1.0
  • MySQL 5.7.18(今回DBは使わないですが、一応。。。)

フォームリクエストバリデーションの作成

フォームリクエストを作成し、その中にバリデーションのルールを記載していきます。

フォームリクエストクラスの作成

$ php artisan make:request CustomRequest

上記コマンドでCustomRequestクラスを作成します。
app/Http/Requests/ 配下にファイル( CustomRequest.php )が作成されています。

フォームリクエストクラスにバリデーションのルールを設定

以下のようにソースを修正します。

app/Http/Requests/CustomRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CustomRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|max:255',
        ];
    }
}

rules メソッドに独自のバリデーションルールを記載しています。
title という項目に対し、 requiredmax:255 という二つのルールを設定しました。

ルール 意味
required 必須項目
max:255 最大255文字まで入力可能

テストコード作成

次に先ほど作成した、フォームリクエストクラスのテストコードを作成します。

フォームリクエストクラスのテストコード作成

$ php artisan make:test CustomRequestTest

上記コマンドでCustomRequestTestクラスを作成します。
デフォルトでは、 tests/Feature 以下に作成されますが、
リクエストのテストということを分かりやすくするため、 tests 配下に Requests ディレクトリを作成します。
そして、その配下に、先ほど作成したファイルを移動します。
tests/Requests/CustomRequestTest.php

テストコード編集

以下のようにテストコードを編集します。

tests/Requests/CustomRequestTest.php
<?php

namespace Tests\Requests;

use Tests\TestCase;
use Illuminate\Support\Facades\Validator;
use App\Http\Requests\CustomRequest;

class CustomRequestTest extends TestCase
{
    /**
     * カスタムリクエストのバリデーションテスト
     *
     * @param string 項目名
     * @param string 値
     * @param boolean 期待値(true:バリデーションOK、false:バリデーションNG)
     * @dataProvider dataproviderExample
     */
    public function testExample($item, $data, $expect)
    {
        //入力項目($item)とその値($data)
        $dataList = [$item => $data];

        $request = new CustomRequest();
        //フォームリクエストで定義したルールを取得
        $rules = $request->rules();
        //Validatorファサードでバリデーターのインスタンスを取得、その際に入力情報とバリデーションルールを引数で渡す
        $validator = Validator::make($dataList, $rules);
        //入力情報がバリデーショルールを満たしている場合はtrue、満たしていな場合はfalseが返る
        $result = $validator->passes();
        //期待値($expect)と結果($result)を比較
        $this->assertEquals($expect, $result);
    }

    public function dataproviderExample()
    {
        return [
            '正常' => ['title', 'タイトル', true],
            '必須エラー' => ['title', '', false],
            //str_repeat('a', 256)で、256文字の文字列を作成(aが256個できる)
            '最大文字数エラー' => ['title', str_repeat('a', 256), false],
        ];
    }

}

説明はコメントに記載した通りになります。
データプロバイダ( dataproviderExample )で testExample に渡す引数(詳細はPHPDoc参照)を指定しています。
※データプロバイダについて、わからない場合は、こちらを参考にしてください。→データプロバイダ

phpunit.xmlの編集

先ほど、tests/Requests 配下にテストコードを移動しましたが、
Requests配下にあるものがテストコードだよ、ということを認識させるために、 phpunit.xml を編集する必要があります。

phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Feature Tests">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="Unit Tests">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Unit Tests">
            <directory suffix="Test.php">./tests/Requests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
    </php>
</phpunit>

phpunit.xml 自体は、Laravelのプロジェクトを作成した時点で用意されており、
今回追加したのは、以下の部分になります。

        <testsuite name="Unit Tests">
            <directory suffix="Test.php">./tests/Requests</directory>
        </testsuite>

./tests/Requests 配下にあるのは、テストコードですよ、ということが認識されるようになります。

テストコード実行

以下のようにしてテストコードを実行します。

$ vendor/bin/phpunit

PHPUnit 5.7.19 by Sebastian Bergmann and contributors.

.....                                                               5 / 5 (100%)

Time: 2.95 seconds, Memory: 12.00MB

OK (5 tests, 5 assertions)

テストが実行され、成功のメッセージが出力されました。

まとめ

今回は、フォームリクエストバリデーションのテストコードを作成しました。
時間を見つけて、他にもテストコードの書き方を記事にしていきたいと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
86
Help us understand the problem. What are the problem?