• Время чтения ~4 мин
  • 30.07.2023

Предварительные требования

В этом руководстве мы протестируем правила проверки регистрации пользователей. Однако эта концепция применима и к другим сценариям. Я предполагаю, что:

Зачем тестировать правила валидации?

  • Чтобы убедиться, что правила проверки работают правильно. Тестирование гарантирует, что приложение не принимает недопустимые данные, которые могут иметь последствия для безопасности или производительности.
  • Для обнаружения ошибок в правилах проверки. С помощью тестов вы можете обнаружить ошибки достаточно рано и предотвратить их проблемы в продакшене.
  • Для улучшения качества кода. Когда вы тестируете свои правила проверки, вы вынуждены думать о том, как они работают и как их следует тестировать.

Тестирование регистрации

пользователей Обновите свой PHPUnit

Я предпочитаю использовать базу данных sqlite :memory: при тестировании своего приложения для простоты. Это не только ускоряет выполнение тестов, но и не требует дополнительной настройки базы данных. phpunit.xml Обновите файл следующим образом.

<!-- <env name="DB_CONNECTION" value="sqlite"/> -->        
<!-- <env name="DB_DATABASE" value=":memory:"/> -->        
<env name="DB_CONNECTION" value="sqlite"/>  
<env name="DB_DATABASE" value=":memory:"/>   

Чтобы обеспечить автоматический перенос базы данных во время тестов, обновите Pest.php файл

uses(
    Tests\TestCase::class,
// Illuminate\Foundation\Testing\RefreshDatabase::class,
Illuminate\Foundation\Testing\LazilyRefreshDatabase::class,
)->in('Feature');

Логика

регистрации Предположим, у вас есть маршрут регистрации,Точка маршрута к вашему контроллеру, который проверяет запрос,

use App\Http\Controllers\RegistrationController;
Route::view('/','welcome')->name('home');
Route::post('/register', RegistrationController::class)->name('register');

создает нового пользователя и перенаправляет на домашнюю страницу:

<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules\Password;
class RegistrationController
{
    public function __invoke(Request $request)
    {
        $validated = $request->validate([
            'name' => ['required', 'string', 'min:4', 'max:80'],
            'email' => ['required', 'email', 'max:100', 'unique:users'],
            'password' => ['required', Password::min(size: 8)->uncompromised(), 'max:64'],
        ]);
        $user = User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
        ]);
        session()->flash(
            key: 'status',
            value: __(
                key: 'messages.user.created',
                replace: ['name' => $user->name]
            )
        );
        return to_route(route: 'home');
    }
}

Где находится

<?php  
  
declare(strict_types=1);  
  
return [  
    'user' => [  
        'created' => "Welcome :name! You're now a member of our community."  
    ]  
];

содержимое lang/en/messages.php файлов Тестирование с наборами

данных pest php Начните с создания нового теста функций с помощью приведенной ниже команды. Новый файл должен быть создан в разделе tests/Feature/Feature/RegistrationControllerTest.php

php artisan make:test Feature/RegistrationControllerTest --pest

Самый простой способ протестировать несколько проверок — использовать наборы данных pest php. Код файла RegistrationControllerTest.php будет выглядеть следующим образом.

<?php

use App\Models\User;
use Illuminate\Support\Str;

function getLongName(): string
{
    return Str::repeat(string: 'name', times: rand(min: 30, max: 50));
}

function getATakenEmail(): string
{
    $takenEmail = '[email protected]';
    User::factory()->create(['email' => $takenEmail]);
    return $takenEmail;
}

dataset(name: 'validation-rules', dataset: [
    'name is required' => ['name', '', fn() => __(key: 'validation.custom.name.required')],
    'name be a string' => ['name', ['array'], fn() => __(key: 'validation.custom.name.string')],
    'name not too short' => ['name', 'ams', fn() => __(key: 'validation.custom.name.min')],
    'name not too long' => ['name', getLongName(), fn() => __(key: 'validation.custom.name.max')],

    'email is required' => ['email', '', fn() => __(key: 'validation.custom.email.required')],
    'email be valid' => ['email', 'esthernjerigmail.com', fn() => __(key: 'validation.custom.email.email')],
    'email not too long' => ['email', fn() => getLongName() . '@gmail.com', fn() => __(key: 'validation.custom.email.max')],
    'email be unique' => ['email', fn() => getATakenEmail(), fn() => __(key: 'validation.custom.email.unique')],

    'password is required' => ['password', '', fn() => __(key: 'validation.custom.password.required')],
    'password be >=8 chars' => ['password', 'Hf^gsg8', fn() => __(key: 'validation.custom.password.min')],
    'password be uncompromised' => ['password', 'password', 'The given password has appeared in a data leak. Please choose a different password.'],
    'password not too long' => ['password', fn() => getLongName(), fn() => __(key: 'validation.custom.password.max')],
]);


it(
    description: 'can validate user inputs',
    closure: function (string $field, string|array $value, string $message) {

    $data = [
        'name' => fake()->name(),
        'email' => fake()->unique()->email(),
        'password' => fake()->password(minLength: 8),
    ];

    $response = $this->post(
        uri: route(name: 'register'),
        data: [...$data, $field => $value]
    );

    $response->assertSessionHasErrors(keys: [$field => $message]);

    $this->assertGuest();
})->with('validation-rules');

Заметка: Порядок правил проверки совпал с порядком в RegistrationController.php

сообщении о проверке Я хочу настроить сообщение о проверке, создав lang/en/validation.php файл и добавив следующее содержимое:

<?php

declare(strict_types=1);

return [

    'custom' => [
        'name' => [
            'required' => 'Please enter your name.',
            'string' => 'Your name is missing.',
            'min' => 'Name is too short. Try your first and last name.',
            'max' => 'Name is too long. Please shorten your name and try again.',
        ],
        'email' => [
            'required' => 'Email address is required.',
            'email' => 'Enter a valid email e.g [email protected].',
            'max' => 'Email is too long. Please shorten your email and try again.',
            'unique' => 'Email is already registered. Try another one or reset password.',
        ],
        'password' => [
            'required' => 'Enter a password.',
            'min'      => 'Password should be at least 8 characters. Add a word or two.',
            'max'      => 'Password needs to be less than 128 characters. Please enter a short one.'
        ],
    ],
];

Выходные данные тестирования Запустите тест, выполнив

команду Выходные данные

vendor/bin/pest --filter="RegistrationControllerTest"

должны выглядеть следующим образом: Pest CLI output

Объяснение

кода «О программе» и getATakenEmail()

«Это getLongName() пользовательская вспомогательная функция, которую я создал для упрощения кода». Они многоразовые и удобные. Дополнительные сведения о вспомогательных функциях см. в документации по

вредителям Структура

наборов данных Рассмотрим следующее подмножество набора данных

dataset(name: 'validation-rules', dataset: [
    'name not too long' => ['name', fn() => getLongName(), fn() => __(key: 'validation.custom.name.max')],
]);
  • name not too long — это необязательное понятное имя набора данных. Я использую его, потому что для улучшения читаемости вывода CLI.
  • validation-rules — имя набора данных.
  • fn() => getLongName() Рекомендуется использовать функцию замыкания, когда вы получаете данные, которые включают в себя вычисления или базу данных.
  • __(key: 'validation.custom.name.max')короткая функция Laravel для получения перевода. Это гарантирует, что вы проверите, что пользователю возвращается правильное сообщение.

Настройка сообщений о проверке Хотя настройка сообщений об ошибках не является обязательной, как дизайнер UI/UX, я понимаю необходимость четких, кратких и полезных сообщений

об ошибках.

Заключение

Наборы данных о вредителях — отличный инструмент для тестирования правил валидации Laravel. Я надеюсь, что вы кое-что узнали о правилах проверки тестирования. Вы можете получить исходный код этого руководства из моего репозитория GitHub

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297