LoginSignup
12
8

More than 5 years have passed since last update.

Laravel ルート定義を取得して一括でHTTPテストする。

Posted at

ルート定義を取得して一括でHTTPテスト、ステータス200が返ってくるかチェックする。
個別にパラメータを定義しておけばパラメータ付きURLのチェックも可能。
基本的に更新系のページは除外。
※Laravelの認証機能を使っている前提で組んであります。

$ php artisan make:test EasyTest
tests/Feature/EasyTest
<?php

namespace Tests\Feature;

use Tests\TestCase;
use \Route;
use App\User;

class EasyTest extends TestCase
{
    private static $user;

    /*
     * 除外設定
     */
    private $easy_route_exclude = [
        '/edit',
        '/reset',
        '/delete',
        '/update',
        '/insert',
        '/login',
        '/logout',
    ];

    /*
     * パラメータ設定
     */
    private $easy_route_params = [
        '[uri]' => [
            [
                '[param_name]' => [param_value],
            ],
        ],
    ];

    public function testGuestLogin()
    {
        $this->get('/')->assertRedirect('login');
    }

    public function testLogin()
    {
        $this->withoutExceptionHandling();
        $response = $this->get('/login');
        $response->assertStatus(200);
    }

    public function testGetUser()
    {
        $this->withoutExceptionHandling();
        self::$user = User::orderBy('id', 'asc')->limit(1)->first();
        $this->assertNotEmpty(self::$user);
    }

    public function testEasyRouteCheck()
    {
        // Route::getRoutes()のデータ量が多いため適当にmemory_limitを変える
        ini_set('memory_limit', '2048M');

        $this->withoutExceptionHandling();
        $check_uri = [];
        $check_method = ['GET', 'POST'];
        $routes = Route::getRoutes()->getRoutesByMethod();
        foreach ($check_method as $method) {
            foreach ($routes[$method] as $v) {
                $uri = $v->uri();
                if ($uri === '/') {
                    continue;
                } else {
                    $uri = '/' . $uri;
                }
                $check = true;
                foreach ($this->easy_route_exclude as $c) {
                    if (strpos($uri, $c) !== false) {
                        $check = false;
                    }
                }
                if ($check === true) {
                    $check_uri[$method][] = $uri;
                }
            }
        }
        foreach ($check_uri as $method => $uris) {
            foreach ($uris as $uri) {
                if ($method === 'POST') {
                    if (isset($this->easy_route_params[$uri])) {
                        $params = $this->easy_route_params[$uri];
                        foreach ($params as $k => $p) {
                            $response = $this->actingAs(self::$user)->post($uri, $p);
                            $response->assertStatus(200);
                        }
                    }
                } else {
                    $response = $this->actingAs(self::$user)->get($uri);
                    $response->assertStatus(200);
                    if (isset($this->easy_route_params[$uri])) {
                        $params = $this->easy_route_params[$uri];
                        foreach ($params as $p) {
                            $param_uri = $uri . '?' . http_build_query($p);
                            $response = $this->actingAs(self::$user)->get($param_uri);
                            $response->assertStatus(200);
                        }
                    }
                }
            }
        }
    }
}

テストを実行

$ vendor/phpunit/phpunit/phpunit

もしくは

$ vendor/phpunit/phpunit/phpunit tests/Feature/EasyTest

テスト前に$this->withoutExceptionHandling()を実行しておかないと、テスト対象のスクリプト内でExceptionが発生してもスルーされる。
しかも$response->assertStatus(200)が通ってしまう。
Webサーバーはステータス500を返しているはずなんだけど、$response->getStatusCode()は200を返す。
この挙動でハマってしまった。
エラーの時に何かするというテストでなければ$this->withoutExceptionHandling()を入れておいた方がようさそう。

12
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8