ラボ > Laravel、Lumen:テスト

laravel テストする

テストコードとユニットテストとか...面倒なやつ

作成日:2025-04-10, 更新日:2025-04-21

ながれ

laravelの場合

  1. 「tests/xxx」の下にテストコードを記載したファイルを置く
  2. コマンド実行

「tests/Feature」の下にテストコードを記載したファイルを置く

<?php

namespace Tests\Feature\Mypage;

// use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class LoginControllerTest extends TestCase
{
  public function test_the_application_returns_a_successful_response()
  {
    // =============================
    // 処理に使う各値たち

    // 無視したいミドルウェア
    $middleware_many = array(
      \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class, // CSRFトークンの対応
      \App\Http\Middleware\●●●::class,
    );

    // 渡したい値
    $data = array(
      'email' => 'user@example.test',
      'password' => 'secret',
    );

    // 実行するURL
    $path = route('●●●');

    // =============================
    // 処理実行

    // POST送信なので「post()」を使う
    $response = $this->withoutMiddleware($middleware_many)->post($path, $data);
    // $response = $this->withoutMiddleware()->post($path, $data); // すべてのミドルウェアを無視
    // $response = $this->post($path, $data); // すべてのミドルウェアを実行

    // =============================
    // 結果の確認: assert●●●()たち

    // $response->assertStatus(302); // リダイレクトを期待する場合
    $response->assertRedirect(route('●●●')); // 成功した場合のリダイレクト先
  }
}

コマンド実行

下記コマンドで「tests」配下の各ファイルを実行してくれる

> php artisan test

※「ExampleTest.php」も実行されるので邪魔なら消しておく

エラーになる: 解決するためにテストをデバッグ

テストを実行すると「$response->assert●●●()」でエラーになると出てくる
どこで、こけているのか調べたい
→任意の場所でログ出力するかvar_dump()する

エラーになる: .envの問題

私の勘違いが原因だった...

処理に「.env」から値を取得して条件分岐させていた
「.env」で「APP_ENV=local」としておりテストを実行すると「config('xxx.ENV_API')」の値が「testing」となる
「local」になってくれないから想定通りの結果になってくれない...という問題が発生

▼対象処理

// 略
if ( strtolower(config('xxx.ENV_API')) == 'local' ) {
  // 略

▼「config('xxx.ENV_API')」の設定: config/xxx.php

// 略
return [
  'ENV_API' => env('ENV_API', config('app.env')),
  // 略

▼事象

  • 「if ( strtolower(config('xxx.ENV_API')) == 'local' )」は「真」になると想定
  • 「config('xxx.ENV_API')」は「testing」になっていた

原因

まずは結論から...

  • 「config/xxx.php」の「env('ENV_API', config('app.env'))」が元凶
    →「.env」に「ENV_API」が無ければ「.env」の「APP_ENV」を使うという設定になる
  • 「.env」では「ENV_API」をコメントしていた
    →config('app.env')が使われた結果、「testing」になっていた

行われていた処理

テストのときは、「.env」ではなく「.env.testing」が使われるそうだ
※「.env.testing」が無ければlaravel側で適切に何かしてくれるっぽい

なので、「config/xxx.php」の「env('ENV_API', config('app.env'))」は
「.env.testing」に「ENV_API」が無ければ「.env.testing」の「APP_ENV」を使うという設定...となる

実際は...

  • 「.env.testing」が無い
  • 「.env」から「ENV_API」を探すが、(コメントしているので)無い
  • 「config('app.env')」を使う
    • 本来は「.env」の「APP_ENV」を使う
    • テストのときは「phpunit.xml」の「APP_ENV」の設定を使う → 「testing」が設定

試したこと

キャッシュのクリア

「php artisan config:clear」だけで良いらしいんだけど、一通りやってみた

$ php artisan route:clear
$ php artisan cache:clear
$ php artisan config:clear
$ php artisan view:clear

「.env.testing」の用意

キャッシュをクリアしてもダメだったんで「.env」を複製して「.env.testing」を作成

「.env.testing」の読み込みの確認

「.env.testing」に「HOGEHOGE=hoge」を追記して、任意のトコで下記出力

$log_data = array(
  'HOGEHOGE' => env('HOGEHOGE'),
);
var_export($log_data);
exit;

キャッシュの再生成

nullになるのでキャッシュを再生成して、再出力したら読み込まれていることを確認できた

$ php artisan config:cache

「env('ENV_API', config('app.env'))」の確認

「.env.testing」に「ENV_API」が無いのでは?というアドバイスをもらって確認
→コメントしていた...

機能テストとユニットテスト

  • 機能テスト: tests/Feature - 一連の処理のテスト
  • ユニットテスト: tests/Unit - 特定のメソッドのテスト

ファイルの作成: 機能テスト用のファイル

▼「tests/Feature/●●●●.php」が作成される

$ php artisan make:test ●●●●

ファイルの作成: ユニットテスト用のファイル

「--unit」を追加

▼「tests/Unit/●●●●.php」が作成される

$ php artisan make:test ●●●● --unit

ファイルの作成: サブディレクトリにつくる

▼「tests/Feature/★★★/●●●●.php」が作成される

$ php artisan make:test ★★★/●●●●

テストの実行コマンドと対象

全部テスト
$ php artisan test
指定したフォルダ配下すべてテスト
$ php artisan test tests/Feature
指定したファイルのみテスト
$ php artisan test tests/Feature/hogeControllerTest.php
指定したファイル(複数)をテスト
$ php artisan test tests/Feature/hogeControllerTest.php tests/Feature/fooControllerTest.php
全ファイルを対象にして、「test_name」が含まれるすべてのメソッドを実行
$ php artisan test --filter test_name

※部分一致

対象ファイルにあるメソッド名に「test_name」が含まれるすべてを実行
$ php artisan test tests/Feature/HogeControllerTest.php --filter test_name

※部分一致

指定した対象メソッドのみ実行
$ php artisan test --filter="HogeControllerTest::test_name"

※完全一致

グループを指定して実行
> php artisan test --group=critical

▼対象: @group アノテーションを設定したメソッドが対象。複数設定可能

/** 
 * @group critical
 * @group critical2
 */
public function test_important_feature()
{
    $this->assertTrue(true);
}

▼設定したグループ名の一覧表示

> php artisan test --list-groups