• Czas czytania ~6 min
  • 30.07.2023

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:

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: Pest CLI output

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

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297