Кез келген бағдарламалау тілінде автоматтандырылған сынақтар немесе бірлік сынақтары туралы сөз болғанда, екі қарама-қарсы пікір бар:
Сонымен, осы мақалада біз біріншіні сендіруге тырысамыз, әсіресе Ларавелде автоматтандырылған тестілеуді бастау қаншалықты оңай екенін көрсету арқылы.
Алдымен «неге» туралы сөйлесейік, содан кейін қалай болатынына бірнеше мысалдарды көрейік.
Автоматтандырылған сынақтар код бөліктерін іске қосады және кез келген қателерді хабарлайды. Бұл оларды сипаттаудың ең қарапайым жолы. Қолданбада жаңа мүмкіндікті шығарып жатқанын елестетіп көріңіз, содан кейін жеке робот көмекшісі барып, жаңа мүмкіндікті қолмен тексереді, сонымен қатар жаңа код ескі мүмкіндіктердің ешқайсысын бұзбағанын тексереді.
Бұл басты артықшылық: барлық мүмкіндіктерді автоматты түрде қайта сынау. Бұл қосымша жұмыс болып көрінуі мүмкін, бірақ егер сіз «роботқа» мұны жаса деп айтпасаңыз, оны қолмен орындау керек емес пе?
Немесе жаңа мүмкіндіктер пайдаланушылар қателер туралы хабарлайды деп үміттеніп, олардың жұмыс істейтінін тексермей-ақ шығарылуы мүмкін.
Автоматтандырылған сынақтар бізге бірнеше артықшылықтар бере алады:
Қолданбаңызды бір-екі жылдан кейін елестетіп көріңіз, командада алдыңғы жылдары жазылған кодты білмейтін, тіпті оны қалай тексеруге болатынын білмейтін жаңа әзірлеушілер бар.
Бірінші орындау үшін Ларавелде автоматтандырылған тестілеу, сізге ешқандай код жазудың қажеті жоқ. Иә, дұрыс оқыдың. Барлығы алдын ала орнатуда конфигурацияланған және дайындалғанdefiЛаравелдің түні, оның ішінде ең бірінші негізгі мысал.
Laravel жобасын орнатуға және бірінші сынақтарды дереу іске қосуға болады:
laravel new project
cd project
php artisan test
Бұл сіздің консольдегі нәтиже болуы керек:
Алдын ала қарайтын болсақdefiЛаравел түні /tests
, бізде екі файл бар:
tests/Feature/ExampleTest.php :
class ExampleTest extends TestCase
{
public function test_the_application_returns_a_successful_response()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
Мұнда не болып жатқанын түсіну үшін ешқандай синтаксисті білудің қажеті жоқ: басты бетті жүктеп, күй кодының бар-жоғын тексеріңіз. HTTP
è «200 OK
«.
Әдіс атауы ретінде де белгілі test_the_application_returns_a_successful_response()
Тек астын сызу белгісін бос орынмен ауыстыру арқылы сынақ нәтижелерін көргенде оқылатын мәтін болады.
tests/Unit/ExampleTest.php :
class ExampleTest extends TestCase
{
public function test_that_true_is_true()
{
$this->assertTrue(true);
}
}
Біраз мағынасыз сияқты, бұл рас па екенін тексеру керек пе?
Бірлік сынақтары туралы сәл кейінірек арнайы айтатын боламыз. Әзірге сіз әр сынақта не болатынын түсінуіңіз керек.
/tests
TestCase кеңейтетін PHP класы болып табылады PHPUitҚұрылымдық жағынан, бұл сізге білу керек нәрсе, қалғанының бәрі сіз сынағыңыз келетін нақты нәрселерге байланысты.
Бос сынақ сыныбын жасау үшін мына пәрменді орындаңыз:
php artisan make:test HomepageTest
Файл жасалады tests/Feature/HomepageTest.php
:
class HomepageTest extends TestCase
{
// Replace this method with your own ones
public function test_example()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
Енді сынақ бекітулері күтілетін нәтижені қайтармаса не болатынын көрейік.
Мысал сынақтарын келесіге өзгертейік:
class ExampleTest extends TestCase
{
public function test_the_application_returns_a_successful_response()
{
$response = $this->get('/non-existing-url');
$response->assertStatus(200);
}
}
class ExampleTest extends TestCase
{
public function test_that_true_is_false()
{
$this->assertTrue(false);
}
}
Ал енді пәрменді орындасақ php artisan test
тағы да:
FAIL Tests\Unit\ExampleTest
⨯ that true is true
FAIL Tests\Feature\ExampleTest
⨯ the application returns a successful response
---
• Tests\Unit\ExampleTest > that true is true
Failed asserting that false is true.
at tests/Unit/ExampleTest.php:16
12▕ * @return void
13▕ */
14▕ public function test_that_true_is_true()
15▕ {
➜ 16▕ $this->assertTrue(false);
17▕ }
18▕ }
19▕
• Tests\Feature\ExampleTest > the application returns a successful response
Expected response status code [200] but received 404.
Failed asserting that 200 is identical to 404.
at tests/Feature/ExampleTest.php:19
15▕ public function test_the_application_returns_a_successful_response()
16▕ {
17▕ $response = $this->get('/non-existing-url');
18▕
➜ 19▕ $response->assertStatus(200);
20▕ }
21▕ }
22▕
Tests: 2 failed
Time: 0.11s
Төменде түсіндірмелерімен және сәтсіз болған сынақтардың нақты жолын көрсететін көрсеткілері бар, FAIL деп белгіленген екі сәтсіз сынақ бар. Қателер осылай көрсетіледі.
Бізде пішін бар және әртүрлі жағдайларды тексеру керек делік: оның жарамсыз деректермен орындалмағанын тексереміз, дұрыс енгізу арқылы сәтті болғанын тексереміз және т.б.
Ресми бастапқы жинақ Ларавел Бриз жазған қамтиды мен оның ішіндегі функционалдылықты тексеру. Сол жерден кейбір мысалдарды қарастырайық:
tests/Feature/RegistrationTest.php
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class RegistrationTest extends TestCase
{
use RefreshDatabase;
public function test_registration_screen_can_be_rendered()
{
$response = $this->get('/register');
$response->assertStatus(200);
}
public function test_new_users_can_register()
{
$response = $this->post('/register', [
'name' => 'Test User',
'email' => 'test@example.com',
'password' => 'password',
'password_confirmation' => 'password',
]);
$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);
}
}
Мұнда бізде бір сыныпта екі сынақ бар, себебі олардың екеуі де тіркеу формасына қатысты: біреуі пішіннің дұрыс жүктелгенін тексереді, ал екіншісі жіберудің жақсы жұмыс істейтінін тексереді.
Нәтижені тексерудің тағы екі әдісімен, тағы екі бекітумен танысайық: $this->assertAuthenticated()
e $response->assertRedirect()
. Сіз ресми құжаттамада бар барлық бекітулерді тексере аласыз PHPUit e Ларавел жауабы . Тақырып бойынша кейбір жалпы бекітулер орын алатынын ескеріңіз $this
, ал басқалары нақтыны тексереді $response
маршруттық қоңыраудан.
Тағы бір маңызды нәрсе use RefreshDatabase;
сөйлем, штрихпен, сыныптың үстіне кірістірілген. Сынақ әрекеттері дерекқорға әсер етуі мүмкін болған кезде қажет, себебі бұл мысалдағы журналда жаңа жазба қосылады users
мәліметтер базасының кестесі. Ол үшін жаңартылатын жеке сынақ дерекқорын жасау керек php artisan migrate:fresh
сынақтар орындалған сайын.
Сізде екі опция бар: жеке дерекқорды физикалық түрде жасау немесе жадтағы SQLite дерекқорын пайдалану. Екеуі де файлда конфигурацияланған phpunit.xml
әдепкі бойынша беріледіdefiнитамен бірге Laravel. Атап айтқанда, сізге бұл бөлік қажет:
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
қараңыз DB_CONNECTION
e DB_DATABASE
қайсысына түсініктеме берілген? Серверіңізде SQLite болса, ең қарапайым әрекет сол жолдарға түсініктеме беру және сынақтар сол жадтағы дерекқорға қарсы орындалады.
Бұл сынақта біз пайдаланушы сәтті аутентификациядан өтіп, дұрыс басты бетке қайта бағытталды деп айтамыз, бірақ дерекқордағы нақты деректерді де тексере аламыз.
Осы кодқа қосымша:
$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);
Біз де пайдалана аламыз деректер базасының сынақ бекітулері және келесідей нәрсені жасаңыз:
$this->assertDatabaseCount('users', 1);
// Or...
$this->assertDatabaseHas('users', [
'email' => 'test@example.com',
]);
Енді Laravel Breeze көмегімен кіру бетінің тағы бір мысалын көрейік
tests/Feature/AuthenticationTest.php:
class AuthenticationTest extends TestCase
{
use RefreshDatabase;
public function test_login_screen_can_be_rendered()
{
$response = $this->get('/login');
$response->assertStatus(200);
}
public function test_users_can_authenticate_using_the_login_screen()
{
$user = User::factory()->create();
$response = $this->post('/login', [
'email' => $user->email,
'password' => 'password',
]);
$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);
}
public function test_users_can_not_authenticate_with_invalid_password()
{
$user = User::factory()->create();
$this->post('/login', [
'email' => $user->email,
'password' => 'wrong-password',
]);
$this->assertGuest();
}
}
Бұл логин пішіні туралы. Логика тіркеуге ұқсас, солай емес пе? Бірақ екеуінің орнына үш әдіс, сондықтан бұл жақсы және жаман сценарийлерді сынаудың мысалы. Осылайша, жалпы логика - сіз екі жағдайды да сынауыңыз керек: істер жақсы болған кезде және олар сәтсіз болғанда.
Сондай-ақ, бұл сынақта сіз оны пайдалану болып табылады Мәліметтер базасы зауыттары : Laravel жалған пайдаланушы жасайды ( қайтадан жаңартылған сынақ дерекқорында ) және содан кейін дұрыс немесе қате тіркелгі деректерімен кіруге әрекеттенеді.
Ларавел тағы да зауытты дайындайдыdefiүшін жалған деректермен nita User
үлгі, қораптан тыс.
database/factories/UserFactory.php:
class UserFactory extends Factory
{
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
Көрдіңіз бе, Ларавелдің өзі қанша нәрсе дайындайды, сондықтан тестілеуді бастау бізге оңай болар ма еді?
Сонымен, егер біз орындасақ php artisan test
Laravel Breeze орнатқаннан кейін біз келесідей нәрсені көруіміз керек:
PASS Tests\Unit\ExampleTest
✓ that true is true
PASS Tests\Feature\Auth\AuthenticationTest
✓ login screen can be rendered
✓ users can authenticate using the login screen
✓ users can not authenticate with invalid password
PASS Tests\Feature\Auth\EmailVerificationTest
✓ email verification screen can be rendered
✓ email can be verified
✓ email is not verified with invalid hash
PASS Tests\Feature\Auth\PasswordConfirmationTest
✓ confirm password screen can be rendered
✓ password can be confirmed
✓ password is not confirmed with invalid password
PASS Tests\Feature\Auth\PasswordResetTest
✓ reset password link screen can be rendered
✓ reset password link can be requested
✓ reset password screen can be rendered
✓ password can be reset with valid token
PASS Tests\Feature\Auth\RegistrationTest
✓ registration screen can be rendered
✓ new users can register
PASS Tests\Feature\ExampleTest
✓ the application returns a successful response
Tests: 17 passed
Time: 0.61s
Ішкі қалталарды көрдіңіз tests/Feature
e tests/Unit
?.
Олардың арасындағы айырмашылық неде?
Дүние жүзінде Laravel/PHP экожүйесінен тыс автоматтандырылған тестілеудің бірнеше түрі бар. Сіз келесідей шарттарды таба аласыз:
Бұл күрделі естіледі және сынақтардың осы түрлерінің арасындағы нақты айырмашылықтар кейде бұлыңғыр болады. Сондықтан Ларавел осы түсініксіз терминдердің барлығын жеңілдетіп, оларды екіге топтады: бірлік/функция.
Қарапайым сөзбен айтқанда, мүмкіндік сынақтары қолданбаларыңыздың нақты функционалдығын орындауға тырысады: URL мекенжайын алыңыз, API шақырыңыз, пішінді толтыру сияқты дәл әрекетті имитациялайды. Мүмкіндік сынақтары әдетте кез келген жоба пайдаланушысы нақты өмірде қолмен жасайтындай немесе ұқсас әрекеттерді орындайды.
Бірлік сынақтарының екі мағынасы бар. Жалпы алғанда, кез келген автоматтандырылған сынақ «бірлік сынағы» деп аталады және бүкіл процесті «бірлік сынағы» деп атауға болады. Бірақ функционалдылық пен бірлік контекстінде бұл процесс белгілі бір жалпыға ортақ емес код бірлігін оқшаулап сынау туралы. Мысалы, сізде параметрлері бар жалпы тапсырыс бағасы сияқты нәрсені есептейтін әдісі бар Laravel сыныбы бар. Сондықтан бірлік сынағы әртүрлі параметрлері бар осы әдістен (код бірлігі) дұрыс нәтижелер қайтарылғанын көрсетеді.
Бірлік сынағын жасау үшін жалаушаны қосу керек:
php artisan make:test OrderPriceTest --unit
Жасалған код блокқа дейінгі сынақпен бірдейdefiLaravel жүйесі:
class OrderPriceTest extends TestCase
{
public function test_example()
{
$this->assertTrue(true);
}
}
Көріп отырғаныңыздай, ол жоқ RefreshDatabase
, және бұл бірі defiең көп тараған бірлік сынақ анықтамалары: ол дерекқорға тимейді, ол іске қосылған қолданбадан оқшауланған «қара жәшік» ретінде жұмыс істейді.
Жоғарыда айтқан мысалға еліктеуге тырысып, бізде қызмет көрсету класы бар деп елестетейік OrderPrice
.
app/Services/OrderPriceService.php:
class OrderPriceService
{
public function calculatePrice($productId, $quantity, $tax = 0.0)
{
// Some kind of calculation logic
}
}
Содан кейін бірлік сынағы келесідей болуы мүмкін:
class OrderPriceTest extends TestCase
{
public function test_single_product_no_taxes()
{
$product = Product::factory()->create(); // generate a fake product
$price = (new OrderPriceService())->calculatePrice($product->id, 1);
$this->assertEquals(1, $price);
}
public function test_single_product_with_taxes()
{
$price = (new OrderPriceService())->calculatePrice($product->id, 1, 20);
$this->assertEquals(1.2, $price);
}
// More cases with more parameters
}
Laravel жобаларымен жеке тәжірибемде, сынақтардың басым көпшілігі бірлік сынақтары емес, мүмкіндік сынақтары болып табылады. Біріншіден, сіз қолданбаңыздың жұмыс істейтінін, нақты адамдар оны қалай пайдаланатынын тексеруіңіз керек.
Әрі қарай, егер сізде арнайы есептеулер немесе логика болса, жасай аласыз definire бірлік ретінде, параметрлері бар, сіз бұл үшін арнайы бірлік сынақтарын жасай аласыз.
Кейде сынақтарды жазу кодтың өзін өзгертуді және оны «тексерілетін» ету үшін қайта өңдеуді талап етеді: бірліктерді арнайы сыныптарға немесе әдістерге бөлу.
Мұның нақты қолданылуы қандай php artisan test
, оны қашан іске қосу керек?
Сіздің бизнесіңіздің жұмыс үрдісіне байланысты әртүрлі тәсілдер бар, бірақ, әдетте, репозиторийге соңғы код өзгерістерін жібермес бұрын барлық сынақтардың «жасыл» (яғни қатесіз) болуын қамтамасыз ету керек.
Содан кейін сіз өзіңіздің тапсырмаңыз бойынша жергілікті түрде жұмыс істейсіз және аяқтадым деп ойласаңыз, ештеңені бұзбағаныңызға көз жеткізу үшін бірнеше сынақтарды орындаңыз. Есіңізде болсын, сіздің кодыңыз тек логикаңызда ғана емес, сонымен қатар әлдеқашан бұрын жазылған басқа біреудің кодындағы кейбір басқа әрекеттерді байқаусызда бұзуы мүмкін.
Бір қадам алға апарсақ, автоматтандыруға болады көп заттар. Әртүрлі CI/CD құралдарымен біреу белгілі бір Git тармағына өзгертулер енгізген сайын немесе кодты өндіріс тармағына біріктіру алдында орындалатын сынақтарды көрсетуге болады. Ең қарапайым жұмыс процесі Github әрекеттерін пайдалану еді, менде бар бөлек бейне бұл дәлелдейді.
«Сынақ қамтуы» деп аталатын ауқымның қаншалықты үлкен болуы керектігі туралы әртүрлі пікірлер бар: әр бетте барлық ықтимал операция мен жағдайды қолданып көріңіз немесе жұмысты ең маңызды бөліктермен шектеңіз.
Шындығында, мен автоматтандырылған тестілеуді нақты пайданы қамтамасыз етуден гөрі көп уақыт алады деп айыптайтын адамдармен келісемін. Әрбір бөлшек үшін сынақтарды жазсаңыз, бұл орын алуы мүмкін. Айтпақшы, бұл сіздің жобаңыз үшін қажет болуы мүмкін: негізгі сұрақ «әлеуетті қатенің бағасы қандай».
Басқаша айтқанда, «Егер бұл код сәтсіз болса не болады?» Деген сұрақты қою арқылы тестілеу әрекеттеріне басымдық беру керек. Төлем жүйеңізде қателер болса, ол бизнеске тікелей әсер етеді. Сондықтан рөлдердің/рұқсаттардың функционалдығы бұзылса, бұл үлкен қауіпсіздік мәселесі.
Маған Мэтт Стауфердің конференцияда айтқан сөзі ұнайды: «Ең алдымен, егер олар сәтсіз болса, сізді жұмысыңыздан босатуға әкелетін нәрселерді сынауыңыз керек». Әрине, бұл асыра сілтеу, бірақ сіз идеяны түсінесіз: алдымен маңызды нәрселерді қолданып көріңіз. Ал содан кейін басқа мүмкіндіктер, егер сізде уақыт болса.
Жоғарыда келтірілген мысалдардың барлығы Laravel алдын ала тестілеу құралына негізделгенdefiтүнде: PHPUit . Бірақ жылдар бойы экожүйеде басқа құралдар пайда болды және ең соңғы танымалдардың бірі PEST . Ларавелдің ресми қызметкері жасаған Нуно Мадуро , синтаксисті жеңілдетуге бағытталған, бұл сынақтар үшін код жазуды тезірек етеді.
Сорғыштың астында ол жүгіреді su PHPUnit қосымша қабат ретінде кейбір алдын ала қайталанатын бөліктерді азайтуға тырысадыdefiPHPUnit кодының соңғы нүктесі.
Бір мысалды қарастырайық. Алдын ала мүмкіндік сынақ сыныбын есте сақтаңызdefiЛаравелде болды ма? Мен сізге еске саламын:
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_the_application_returns_a_successful_response()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
PEST-пен бірдей сынақтың қандай болатынын білесіз бе?
test('the application returns a successful response')->get('/')->assertStatus(200);
Иә, кодтың БІР жолы және бұл. Сонымен, PEST мақсаты келесі шығындарды жою болып табылады:
Laravel-те PEST тестін жасау үшін қосымша жалаушаны көрсету керек:
php artisan make:test HomepageTest --pest
Осы жазу кезінде PEST Laravel әзірлеушілері арасында өте танымал, бірақ бұл қосымша құралды пайдалану және оның синтаксисін, сондай-ақ PHPUnit жазбасын үйрену сіздің жеке қалауыңыз.
BlogInnovazione.it
Өткен дүйсенбіде Financial Times OpenAI-мен келісім туралы жариялады. FT өзінің әлемдік деңгейдегі журналистикасына лицензия береді…
Миллиондаған адамдар ай сайынғы абоненттік төлемді төлей отырып, ағынды қызметтерге ақы төлейді. Жалпы пікір, сіз…
Veeam ұсынған Coveware кибербопсалау оқиғаларына жауап беру қызметтерін көрсетуді жалғастырады. Coveware криминалистикалық және қалпына келтіру мүмкіндіктерін ұсынады ...
Болжалды техникалық қызмет көрсету зауытты басқаруға инновациялық және белсенді көзқараспен мұнай және газ секторында төңкеріс жасайды.…