Кога станува збор за автоматизирани тестови или единечни тестови, во кој било програмски јазик, постојат две спротивставени мислења:
Така, со оваа статија ќе се обидеме да го убедиме првиот, особено со тоа што ќе покажеме колку е лесно да се започне со автоматско тестирање во Ларавел.
Прво да разговараме за „зошто“, а потоа да видиме неколку примери за тоа како.
Автоматските тестови извршуваат делови од кодот и известуваат за какви било грешки. Тоа е наједноставниот начин да ги опишете. Замислете да стартувате нова функција во апликација, а потоа личен асистент робот ќе отиде и рачно ќе ја тестира новата функција, а исто така ќе тестира дали новиот код не скрши ниту една од старите функции.
Ова е главната предност: повторно тестирање на сите функции автоматски. Ова може да изгледа како дополнителна работа, но ако не му кажете на „роботот“ да го направи тоа, алтернативно треба да го направиме рачно, нели?
Или, пак, нови функции би можеле да бидат објавени без тестирање дали функционираат, надевајќи се дека корисниците ќе пријават грешки.
Автоматските тестови можат да ни дадат неколку предности:
Обидете се да ја замислите вашата апликација за една или две години, со нови програмери во тимот кои не го знаат кодот напишан во претходните години, па дури и како да го тестираат.
Да се изврши првата автоматско тестирање во Ларавел, не треба да пишувате никаков код. Да, добро прочитавте. Сè е веќе конфигурирано и подготвено во прединсталацијатаdefinite of Laravel, вклучувајќи го и првиот основен пример.
Може да се обидете да инсталирате проект Laravel и веднаш да ги извршите првите тестови:
laravel new project
cd project
php artisan test
Ова треба да биде резултат во вашата конзола:
Ако погледнеме на предdefiноќта на Ларавел /tests
, имаме две датотеки:
тестови/Функција/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()
станува читлив текст кога ги гледате резултатите од тестот, едноставно со замена на подвлечениот симбол со празно место.
тестови/Единица/Пример Тест.php :
class ExampleTest extends TestCase
{
public function test_that_true_is_true()
{
$this->assertTrue(true);
}
}
Изгледа малку бесмислено, проверувам дали е ова вистина?
Ќе зборуваме конкретно за единечните тестови малку подоцна. Засега, треба да разберете што генерално се случува во секој тест.
/tests
е класа PHP што го проширува TestCase на PHPU-единицаСтруктурно, тоа е сè што треба да знаете, сè друго зависи од точните работи што сакате да ги тестирате.
За да генерирате празна тест класа, едноставно извршете ја оваа команда:
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, со објаснувања подолу и стрелки што укажуваат на точната линија на тестови што не успеале. Грешките се наведени на овој начин.
Да претпоставиме дека имаме формулар и треба да тестираме различни случаи: проверуваме дали не успева со невалидни податоци, проверуваме дали успева со точниот внес итн.
Официјалниот стартен комплет од Ларавел Бриз вклучува i тестирање на функционалноста во него. Ајде да погледнеме неколку примери од таму:
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()
. Можете да ги проверите сите тврдења достапни во официјалната документација на PHPU-единица 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 создава лажен корисник ( повторно, на вашата ажурирана база на податоци за тестирање ) и потоа се обидува да се најави, со точни или неточни ингеренции.
Уште еднаш, Laravel го генерира фабричкиот предdefiнита со лажни податоци за на 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
Генерираниот код е ист како тестот пред единицатаdefiЛаравел систем:
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
}
Според моето лично искуство со проектите на Ларавел, огромното мнозинство на тестови се Тестови за карактеристики, а не за единици. Прво, треба да тестирате дали вашата апликација работи, како што би ја користеле вистинските луѓе.
Следно, ако имаш посебни пресметки или логика можеш definire како единица, со параметри, можеш да креираш единечни тестови специјално за тоа.
Понекогаш, пишувањето тестови бара модифицирање на самиот код и негово рефакторирање за да се направи повеќе „проверлив“: одвојување на единиците во посебни класи или методи.
Која е вистинската употреба на ова php artisan test
, кога треба да го стартувате?
Постојат различни пристапи, во зависност од работниот тек на вашиот бизнис, но генерално треба да се осигурате дека сите тестови се „зелени“ (т.е. без грешки) пред да ги турнете конечните промени на кодот во складиштето.
Потоа, работите локално на вашата задача и кога мислите дека сте готови, извршете неколку тестови за да бидете сигурни дека не сте скршиле ништо. Запомнете, вашиот код може да предизвика грешки не само во вашата сопствена логика, туку и ненамерно да скрши некое друго однесување во туѓиот код напишан одамна.
Ако одиме чекор понатаму, можно е да се автоматизира молте работи. Со различни CI/CD алатки, можете да одредите тестови да се извршуваат секогаш кога некој ќе турка промени во одредена Git гранка или пред да го спои кодот во производствената гранка. Наједноставниот работен тек би бил користењето Github Actions, јас го имам посебно видео што го докажува тоа.
Постојат различни мислења за тоа колку голема треба да биде таканаречената „покриеност за тестирање“: испробајте ја секоја можна операција и случај на секоја страница или ограничете ја работата на најважните делови.
Всушност, ова е местото каде што се согласувам со луѓето кои обвинуваат дека автоматското тестирање одзема повеќе време отколку да обезбеди вистинска корист. Ова може да се случи ако напишете тестови за секој детал. Како што рече, тоа може да го бара вашиот проект: главното прашање е „која е цената на потенцијалната грешка“.
Со други зборови, треба да им дадете приоритет на вашите напори за тестирање поставувајќи го прашањето „Што би се случило ако овој код не успее? Ако вашиот систем за плаќање има грешки, тоа директно ќе влијае на бизнисот. Значи, ако функционалноста на вашите улоги/дозволи е нарушена, ова е огромен безбедносен проблем.
Ми се допаѓа како Мет Стауфер го кажа на конференција: „Прво мора да ги тестирате оние работи кои, доколку не успеат, ќе ве отпуштат од работата“. Се разбира, тоа е претерување, но ја разбирате идејата: прво пробајте ги важните работи. А потоа и други карактеристики, ако имате време.
Сите горенаведени примери се засноваат на алатката за претходно тестирање на Ларавелdefiноќ: PHPU-единица . Но, со текот на годините се појавија други алатки во екосистемот и една од најновите популарни е ШТЕТНИК . Создаден од официјален вработен во Ларавел Нуно Мадуро , има за цел да ја поедностави синтаксата, правејќи го пишувањето код за тестови уште побрзо.
Под хаубата, работи su PHPUnit, како дополнителен слој, само се обидува да минимизира некои претходно повторени деловиdefiнита од кодот PHPUnit.
Ајде да погледнеме на пример. Запомнете ја класата за тестирање пред карактеристики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 е да ги отстрани трошоците за:
За да генерирате PEST тест во Ларавел, треба да наведете дополнително знаменце:
php artisan make:test HomepageTest --pest
Од моментот на пишување, PEST е доста популарен меѓу развивачите на Laravel, но ваша лична претпочита е дали да ја користите оваа дополнителна алатка и да ја научите нејзината синтакса, како и белешката PHPUnit.
BlogInnovazione.it
Coveware од Veeam ќе продолжи да обезбедува услуги за одговор на инциденти на сајбер изнуда. Coveware ќе понуди форензика и способности за санација…
Предвидливото одржување го револуционизира секторот за нафта и гас, со иновативен и проактивен пристап кон управувањето со постројките.…
Обединетото Кралство CMA издаде предупредување за однесувањето на Big Tech на пазарот на вештачка интелигенција. Таму…
Уредбата за „Case Green“, формулирана од Европската унија за подобрување на енергетската ефикасност на зградите, го заврши својот законодавен процес со…