Предварительные требования
В этом руководстве мы протестируем правила проверки регистрации пользователей. Однако эта концепция применима и к другим сценариям. Я предполагаю, что:
- Вы знаете, как настроить приложение Laravel. Если нет, вы можете обратиться к официальной документации Laravel
- Вы знакомы с фреймворком тестирования Pest PHP. Если нет, обратитесь к документации Pest PHP.
Зачем тестировать правила валидации?
- Чтобы убедиться, что правила проверки работают правильно. Тестирование гарантирует, что приложение не принимает недопустимые данные, которые могут иметь последствия для безопасности или производительности.
- Для обнаружения ошибок в правилах проверки. С помощью тестов вы можете обнаружить ошибки достаточно рано и предотвратить их проблемы в продакшене.
- Для улучшения качества кода. Когда вы тестируете свои правила проверки, вы вынуждены думать о том, как они работают и как их следует тестировать.
Тестирование регистрации
пользователей Обновите свой 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"
должны выглядеть следующим образом:
Объяснение
кода «О программе» и 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