Wymagania wstępne
W tym przewodniku przetestujemy reguły sprawdzania poprawności rejestracji użytkowników. Koncepcja ta ma jednak zastosowanie do innych scenariuszy. Zakładam, że:
- Wiesz, jak skonfigurować aplikację Laravel. Jeśli nie, możesz zapoznać się z oficjalną dokumentacją Laravela
- Znasz framework testowy Pest PHP. Jeśli nie, zapoznaj się z dokumentacją PHP Pest..
Dlaczego warto testować reguły sprawdzania poprawności?
- Aby upewnić się, że reguły sprawdzania poprawności działają poprawnie. Testowanie gwarantuje, że aplikacja nie akceptuje nieprawidłowych danych, co może mieć wpływ na bezpieczeństwo lub wydajność.
- Aby wykryć błędy w regułach sprawdzania poprawności. Dzięki testom możesz wystarczająco wcześnie wychwycić błędy i zapobiec problemom w produkcji.
- Aby poprawić jakość kodu. Podczas testowania reguł sprawdzania poprawności użytkownik jest zmuszony zastanowić się, jak działają i jak powinny być testowane.
Testowanie rejestracji
użytkowników Zaktualizuj PHPUnit
Wolę używać bazy danych sqlite :memory:
podczas testowania mojej aplikacji dla uproszczenia. Nie tylko przyspiesza to testy, ale także nie wymaga dodatkowej konfiguracji bazy danych. phpunit.xml
Zaktualizuj plik w następujący sposób.
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
Aby zapewnić automatyczną migrację bazy danych podczas testów, zaktualizuj Pest.php
plik
uses(
Tests\TestCase::class,
// Illuminate\Foundation\Testing\RefreshDatabase::class,
Illuminate\Foundation\Testing\LazilyRefreshDatabase::class,
)->in('Feature');
Logika
rejestracji Załóżmy, że masz trasę rejestracji, punkt trasy do kontrolera, który sprawdza poprawność żądania,
use App\Http\Controllers\RegistrationController;
Route::view('/','welcome')->name('home');
Route::post('/register', RegistrationController::class)->name('register');
tworzy nowego użytkownika i przekierowuje do strony głównej:
<?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');
}
}
Gdzie znajduje
<?php
declare(strict_types=1);
return [
'user' => [
'created' => "Welcome :name! You're now a member of our community."
]
];
się zawartość lang/en/messages.php
plików
Testowanie z zestawami
danych php szkodników Zacznij od utworzenia nowego testu funkcji za pomocą poniższego polecenia. Nowy plik powinien zostać utworzony w obszarze tests/Feature/Feature/RegistrationControllerTest.php
php artisan make:test Feature/RegistrationControllerTest --pest
Najprostszym sposobem testowania wielu walidacji jest użycie zestawów danych php szkodników. Kod RegistrationControllerTest.php
pliku wyglądałby tak.
<?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');
Nuta: Kolejność reguł sprawdzania poprawności była zgodna z kolejnością w
RegistrationController.php
komunikacie Chcę dostosować sprawdzanie poprawności przez utworzenie lang/en/validation.php
pliku i dodanie następującej zawartości:
<?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.'
],
],
];
Dane wyjściowe testowaniaDane wyjściowe
Dane wyjściowe
vendor/bin/pest --filter="RegistrationControllerTest"
powinny wyglądać następująco:
Wyjaśnienie
kodu O getLongName()
i getATakenEmail()
Są to niestandardowe funkcje pomocnicze, które stworzyłem, aby uprościć kod. Są wielokrotnego użytku i wygodne. Więcej informacji na temat funkcji pomocniczych można znaleźć w dokumentacji
dotyczącej szkodników: Struktura
zbiorów danych: Rozważmy następujący podzbiór zestawu danych:
dataset(name: 'validation-rules', dataset: [
'name not too long' => ['name', fn() => getLongName(), fn() => __(key: 'validation.custom.name.max')],
]);
-
name not too long
jest opcjonalną, przyjazną dla człowieka nazwą zbioru danych. Używam go, ponieważ poprawia czytelność wyjścia cli. -
validation-rules
jest nazwą zestawu danych. -
fn() => getLongName()
Zaleca się użycie funkcji zamykania w przypadku uzyskania danych obejmujących obliczenia lub bazę danych. -
__(key: 'validation.custom.name.max')
krótka funkcja Laravel do pobierania tłumaczenia. Zapewni to, że do użytkownika jest zwracany poprawny komunikat.
Dostosowywanie komunikatów sprawdzania poprawności Chociaż dostosowanie komunikatów o błędach nie jest obowiązkowe, jako projektant UI / UX rozumiem potrzebę jasnych, zwięzłych i pomocnych komunikatów
o błędach.
Wnioski:
Zbiory danych szkodników są doskonałym narzędziem do testowania reguł walidacji Laravel. Mam nadzieję, że nauczyłeś się czegoś o testowaniu reguł walidacji. Możesz pobrać kod źródłowy tego przewodnika z mojego repozytorium GitHub