LoginSignup
24
27

More than 5 years have passed since last update.

Laravel でログインの結合テストを書く

Last updated at Posted at 2017-03-13

簡単だった。さすがLaravel。

テストの無かったアプリケーションに、テストを導入した。
まずはクリティカルなログインをカバーする。

実際にテストを書くよりも、環境作ったり、 Seeder 作ったりする過程の方が長かった。
最初から環境が整ってれば別だが・・・。

環境

  • Laravel 5.1
  • PHP 7.0.13

対象コード (一部)

普通のログインフォーム。

resources/views/auth/login.blade.php
<form method="POST" action="{{ url('/auth/user-login') }}">
  <input id="email" type="email" name="email" placeholder="">
  <input id="password" type="password" name="password">
  <button type="submit">ログイン</button>
</form>
app/Http/Controllers/Auth/AuthController.php
    // ログイン処理
    public function userLogin(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if ($this->auth->attempt($credentials)) {
            return redirect()->intended('/home');
        }
    }

Factory

適当なユーザーを作るやつ。これ便利だなー。

database/factories/UserFactory.php
<?php

$factory->define(App\Models\User::class, function(Faker\Generator $faker) {
    return [
        'name'      => $faker->name,
        'email'     => $faker->unique()->companyEmail,
        'password'  => bcrypt('secret'),
    ];
});

テストコード

すごく直感的。

DatabaseTransactions トレイトにより、作成したユーザーは、メソッド終了と同時にロールバックされる。これも便利だなー。

tests/Integration/UserLoginTest.php
<?php

namespace Tests\Integration;

use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Models\User;
use Tests\TestCase;

class UserLoginTest extends TestCase
{

    use DatabaseTransactions;

    public function testUserLoginByEmail()
    {
        $user = factory(User::class, 'student')->create();

        $this->visit('/login')
             ->type($user->email, 'email')
             ->type('secret', 'password')
             ->press('ログイン')
             ->seePageIs('/home');
    }
}
tests/TestCase.php(一部)
<?php

abstract class TestCase extends BaseTestCase
{
    public function createApplication()
    {
        // testing 環境でもlocal 環境を見に行ってしまうため
        // キャッシュを読み込まないようにしている
        if (file_exists(__DIR__.'/../bootstrap/cache/config.php'))
            unlink(__DIR__.'/../bootstrap/cache/config.php');
    }
}

abstract にしておかないとPHPUnitがテストしようとしてエラーを吐く。

なお、 Tests\ という namespace は標準で付いていないので、 composer.jsonPSR-4 オートローダーを設定する必要がある。

composer.json
    "psr-4": {
      "App\\": "app/",
      "Tests\\": "tests/"
    }

[追記]

autoload-dev に追加した方が良い。本番のパフォーマンスにわずかに影響するかも?

[/追記]

[さらに追記]

そもそも名前空間を指定しなくて良いという意見もある。指定しないと何となく不安になる、ディレクトリ構造とファイル名が対応しなくなるなどの弊害があるかもしれないが、そもそも PHPUnit がファイルを探してテストを実行するので、オートロードする必要も無い。

[/さらに追記]

実行

......                              

Time: 2.15 seconds, Memory: 22.00MB 

OK (1 tests, 5 assertions)         

成功すると気分がいいですね。

参考

24
27
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
24
27