# Laravel Test についてのメモ

Laravel 使って自動テストを行う作業があったので、メモして起きます。
tests ディレクトリの下 Feature と Unit ディレクトリにそれぞれのテストクラスを設置できます。

  • Feature 機能テスト、全体テスト
    • /tests/Feature 配下
  • Unit ユニットテスト、単体テスト
    • /tests/Unit 配下

ユニットテストは Laravel アプリケーションを起動しないため、アプリケーションのデータベースやその他のフレームワークサービスにアクセスできません

機能テストはシステム全体が意図したとおりの機能も用いてログインした状態でアクセス時の動作テスト、検索パラメータ付けたアクセス時の動作確認ができます。

# テスト実行コマンド

# 作成

php artisan make:test UserTest

デフォルトは tests/Feature ディレクトリへ配置
--unitオプション使う場合tests/Unitディレクトリへ配置

# テスト実行コマンド

# phpunit
./vendor/bin/phpunit

# artisan
php artisan test

phpunit と Artisan の違い

  • Artisan テストは詳細なテストレポートを提供
  • phpunit コマンドで使用できる引数はすべて Artisan test コマンドにも渡せます。
php artisan test --testsuite=Feature --stop-on-failure

# サンプル

# テスト作る

php artisan make:test UserTest

# テストファイル編集

Faker 使ってデータ生成しながら、テストファイル編集

<?php

namespace Tests\Feature;

use Faker;
use Tests\TestCase;

class UserTest extends TestCase
{

    public function test_example()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

    public function test_login()
    {
        $faker = Faker\Factory::create();
        $response = $this->post('/login', [
            'email' => $faker->email(),
            'password' => 'test',
        ]);

        $response->assertStatus(200);
    }
}

# テストコマンド実行

php artisan test
#  PASS  Tests\Unit\ExampleTest
# ✓ example
#
#  PASS  Tests\Feature\ExampleTest
# ✓ example
#
#  PASS  Tests\Feature\UserTest
# ✓ example
# ✓ login
#
# Tests:  4 passed
# Time:   0.78s

# テストを並列で実行 --parallel オプション

php artisan test --parallel

--parallel オプション使うことでテスト時間を大幅に削減できます。

デフォルトではマシン CPU コアの数だけプロセスを作成されますが、--processes オプション付けることでプロセス数を調整できます。

php artisan test --parallel --processes=4

.env.testing ファイルは --env=testingオプションの際に使用されます。

# Faker のよく使うメソッド

メソッド 説明
$faker->lastName
$faker->firstName
$faker->name 姓名
$faker->address 住所
$faker->postcode 郵便番号
$faker->phoneNumber 電話番号
$faker->country
$faker->email メールアドレス
$faker->safeEmail 安全メールアドレス
$faker->freeEmail 無料メールアドレス
$faker->companyEmail 企業メールアドレス
$faker->freeEmailDomain 無料メールアドレスドメイン
$faker->safeEmailDomain 安全メールアドレスドメイン
$faker->userName ユーザーネーム
$faker->password パスワード
$faker->domainName ドメイン
$faker->url URL
$faker->slug スラグ文字列
$faker->ipv4 ipv4 IP
$faker->localIpv4 ipv4 IP
$faker->ipv6 ipv6 IP
$faker->macAddress Mac アドレス

# uploadedFile ファイルアップロードのテスト

画像ファイル

<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
    public function testAvatarUpload()
    {
        Storage::fake('avatars');
        $response = $this->json('POST', '/avatar', [
            'avatar' => UploadedFile::fake()->image('avatar.jpg')
        ]);
        // ファイルが保存されたことをアサートする
        Storage::disk('avatars')->assertExists('avatar.jpg');
        // ファイルが存在しないことをアサートする
        Storage::disk('avatars')->assertMissing('missing.jpg');
    }
}

# サイズ指定画像アップロード

UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

# PDF ファイルアップロード

UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

# エクセルファイルアップロード

$response = $this->post(route('users.excel.import.upload'), [
            'users' => UploadedFile::fake()->create(
                name: 'users.xlsx',
                mimeType: 'application/vnd.openxmlformats-officedocument.spread'
            )
        ]);

# CSV ファイルアップロード

 $header = 'Header 1,Header 2,Header 3';
    $row1 = 'value 1,value 2,value 3';
    $row2 = 'value 1,value 2,value 3';

    $content = implode("\n", [$header, $row1, $row2]);

    $inputs = [
        'csv_file' =>
            UploadedFile::
                fake()->
                createWithContent(
                    'test.csv',
                    $content
                )
    ];


    $response = $this->postJson(
        'file-upload',
        $inputs

    );

    $response->assertOk();

# 利用可能なアサート

json、get、post、put、delete

レスポンスアサート
assertCookie $response->assertCookie($cookieName, $value = null); クッキー持っている
assertCookieExpired $response->assertCookieExpired($cookieName); クッキー期限切れである
assertCookieNotExpired $response->assertCookieNotExpired($cookieName); クッキー期限切れでない
assertCookieMissing $response->assertCookieMissing($cookieName); クッキーを持っていない
assertDontSee $response->assertDontSee($value); 指定した文字列がレスポンスに含まれていない
assertDontSeeText $response->assertDontSeeText($value); 指定した文字列がレスポンステキストに含まれていない
assertExactJson $response->assertExactJson(array $data); 指定した JSON データと完全に一致する
assertForbidden $response->assertForbidden(); forbidden ステータスコードを持っている
assertHeader $response->assertHeader($headerName, $value = null); 指定したヘッダが存在している
assertHeaderMissing $response->assertHeaderMissing($headerName); 指定したヘッダが存在していない
assertJson $response->assertJson(array $data); 指定した JSON データを持っている
assertJsonCount $response->assertJsonCount($count, $key = null); 指定したキーのアイテムを、期待値分持っている
assertJsonFragment $response->assertJsonFragment(array $data); 指定した JSON の一部を含んでいる
assertJsonMissing $response->assertJsonMissing(array $data); 指定した JSON の一部を含んでいない
assertJsonMissingExact $response->assertJsonMissingExact(array $data); JSON の一部をそのまま含んでいない
assertJsonStructure $response->assertJsonStructure(array $structure); 指定した JSON の構造を持っている
assertJsonValidationErrors $response->assertJsonValidationErrors($keys); 指定した JSON バリデーションエラーを持っている
assertLocation $response->assertLocation($uri); Location ヘッダが、指定した URI を持っている
assertNotFound $response->assertNotFound(); not found のステータスコードを持っている
assertOk $response->assertOk(); 200 のステータスコードを持っている
assertPlainCookie $response->assertPlainCookie($cookieName, $value = null); 指定した暗号化されていないクッキーを持っている
assertRedirect $response->assertRedirect($uri); 指定した URI へリダイレクトする
assertSee $response->assertSee($value); 指定した文字列がレスポンスに含まれている
assertSeeInOrder $response->assertSeeInOrder(array $values); 指定した文字列が、順番通りにレスポンスに含まれている
assertSeeText $response->assertSeeText($value); 指定した文字列がレスポンステキストに含まれている
assertSeeTextInOrder $response->assertSeeTextInOrder(array $values); 指定した文字列が、順番通りにレンスポンステキストへ含まれている
assertSessionHas $response->assertSessionHas($key, $value = null); セッションが指定したデータを持っている
assertSessionHasAll $response->assertSessionHasAll(array $data); セッションが指定したリストの値を持っている
assertSessionHasErrors $response->assertSessionHasErrors(array $keys, $format = null, $errorBag = 'default'); セッションが指定したフィールドに対するエラーを含んでいる
assertSessionHasErrorsIn $response->assertSessionHasErrorsIn($errorBag, $keys = [], $format = null); セッションが指定したエラーを持っている
assertSessionHasNoErrors $response->assertSessionHasNoErrors(); セッションがエラーを持っていない
assertSessionMissing $response->assertSessionMissing($key); セッションが指定したキーを持っていない
assertStatus $response->assertStatus($code); 指定したコードである
assertSuccessful $response->assertSuccessful(); 成功のステータスコードである
assertViewHas $response->assertViewHas($key, $value = null); 指定したデータを持っている
assertViewHasAll $response->assertViewHasAll(array $data); 指定したリストのデータを持っている
assertViewIs $response->assertViewIs($value); 指定したビューが返された
assertViewMissing $response->assertViewMissing($key); 指定したデータを持っていない

# 認証のアサート

メソッド 説明
$this->assertAuthenticated($guard = null); ユーザーが認証されている
$this->assertGuest($guard = null); ユーザーが認証されていない
$this->assertAuthenticatedAs($user, $guard = null); 指定したユーザーが認証されている
$this->assertCredentials(array $credentials, $guard = null); 指定した認証情報が有効である
$this->assertInvalidCredentials(array $credentials, $guard = null); 指定した認証情報が無効である
2022-06-10

同じタグを持つ記事をピックアップしました。