Artikel

Sinau carane nindakake tes ing Laravel kanthi conto sing gampang, nggunakake PHPUnit lan PEST

Nalika nerangake tes otomatis utawa tes unit, ing basa pamrograman apa wae, ana rong panemu sing nentang:

  • Mbuang wektu
  • Sampeyan ora bisa nindakake tanpa iku

Dadi, karo artikel iki kita bakal nyoba kanggo gawe uwong yakin mantan, utamané dening nuduhake carane gampang iku kanggo miwiti karo testing otomatis ing Laravel.

Pisanan ayo ngomong babagan "kenapa", banjur ayo ndeleng sawetara conto carane.

Napa kita butuh tes otomatis

Tes otomatis mbukak bagean kode lan nglaporake kesalahan. Iku cara paling gampang kanggo njlèntrèhaké wong. Bayangake muter fitur anyar ing app, banjur asisten robot pribadhi bakal nyoba kanthi manual fitur anyar, nalika uga nyoba apa kode anyar ora break fitur lawas.

Iki minangka kauntungan utama: tes maneh kabeh fitur kanthi otomatis. Iki bisa uga katon kaya karya ekstra, nanging yen sampeyan ora ngandhani "robot" kanggo nindakake, kita kudu nindakake kanthi manual, ta? 

Utawa fitur-fitur anyar bisa diluncurake tanpa nyoba apa bisa digunakake, ngarep-arep pangguna bakal nglaporake bug.

Tes otomatis bisa menehi sawetara kaluwihan:

  • Ngirit wektu testing manual;
  • Dheweke ngidini sampeyan ngirit wektu ing fungsi anyar sing diimplementasikake lan ing fungsi gabungan kanthi ngindhari regresi;
  • Multiply keuntungan iki dening kabeh fitur anyar lan kabeh fitur wis dileksanakake;
  • Telung poin sadurunge ditrapake kanggo saben versi anyar;
  • ...

Coba bayangake aplikasi sampeyan ing setahun utawa rong taun, karo pangembang anyar ing tim sing ora ngerti kode sing ditulis ing taun-taun sadurunge, utawa malah carane nyoba. 

Tes otomatis pisanan kita

Kanggo nindakake pisanan testing otomatis ing Laravel, sampeyan ora perlu nulis kode apa wae. Ya, sampeyan maca sing bener. Kabeh wis dikonfigurasi lan disiapake ing pra-instaldefinite saka Laravel, kalebu conto dhasar banget pisanan.

Sampeyan bisa nyoba nginstal proyek Laravel lan langsung mbukak tes pisanan:

laravel new project
cd project
php artisan test

Iki kudu dadi asil ing konsol sampeyan:

Yen kita deleng pradefiwengi saka Laravel /tests, kita duwe rong file:

tests/Fitur/ExampleTest.php :

class ExampleTest extends TestCase
{
    public function test_the_application_returns_a_successful_response()
    {
        $response = $this->get('/');
 
        $response->assertStatus(200);
    }
}

Sampeyan ora perlu ngerti sintaks kanggo ngerti apa sing kedadeyan ing kene: muat kaca ngarep lan priksa manawa kode status HTTP è "200 OK".

Uga dikenal minangka jeneng metode test_the_application_returns_a_successful_response() dadi teks sing bisa diwaca nalika ndeleng asil tes, mung kanthi ngganti simbol garis ngisor kanthi spasi.

tests/Unit/ExampleTest.php :

class ExampleTest extends TestCase
{
    public function test_that_true_is_true()
    {
        $this->assertTrue(true);
    }
}

Kayane rada ora ana gunane, priksa manawa iki bener? 

Kita bakal ngomong khusus babagan tes unit mengko. Saiki, sampeyan kudu ngerti apa sing umume kedadeyan ing saben tes.

  • Saben file test ing folder /tests iku kelas PHP sing ngluwihi TestCase saka PHPUnit
  • Ing saben kelas, sampeyan bisa nggawe macem-macem cara, biasane siji cara kanggo nyoba kahanan
  • Ing saben cara ana telung tumindak: nyiapake kahanan, banjur tumindak banjur verifikasi (menegaskan) apa asile wis samesthine.

Sacara struktural, sampeyan mung kudu ngerti, kabeh liya gumantung saka prekara sing pengin dites.

Kanggo ngasilake kelas tes kosong, jalanake printah iki:

php artisan make:test HomepageTest

File digawe 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);
    }
}

Saiki ayo ndeleng apa sing kedadeyan yen kode tes gagal ing Laravel

Ayo saiki ndeleng apa sing kedadeyan yen pratelan tes ora ngasilake asil sing dikarepake.

Ayo ngganti conto tes iki:

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);
    }
}

Lan saiki, yen kita mbukak printah php artisan test maneh:

 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

Ana rong tes sing gagal, ditandhani minangka GAGAL, ​​kanthi panjelasan ing ngisor iki lan panah nuduhake garis tes sing gagal. Kasalahan dituduhake kanthi cara iki.

Conto: Nguji kode formulir registrasi ing Laravel

Upaminipun kita duwe formulir lan kita kudu nyoba macem-macem kasus: kita mriksa yen gagal karo data ora bener, kita mriksa yen sukses karo input bener, etc.

Kit wiwitan resmi dening Laravel Breeze kalebu i nguji fungsi ing njero. Ayo ndeleng sawetara conto saka ing kono:

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);
    }
}

Ing kene kita duwe rong tes ing siji kelas, amarga loro-lorone ana hubungane karo formulir registrasi: siji mriksa yen formulir kasebut dimuat kanthi bener lan liyane mriksa manawa kiriman kasebut bisa digunakake.

Ayo dadi akrab karo rong cara liyane kanggo verifikasi asil, rong pratelan liyane: $this->assertAuthenticated()$response->assertRedirect(). Sampeyan bisa mriksa kabeh pratelan sing kasedhiya ing dokumentasi resmi saka PHPUnit e Tanggapan Laravel . Elinga yen sawetara pratelan umum dumadi ing subyek $this, nalika liyane mriksa tartamtu $responsesaka telpon rute.

Liyane sing penting yaiku use RefreshDatabase;statement, karo stroke, dipasang ing ndhuwur kelas. Sampeyan perlu nalika tumindak test bisa mengaruhi database, kaya ing conto iki, logging nambah entri anyar ing userstabel database. Kanggo iki, sampeyan kudu nggawe database test kapisah sing bakal dianyari karo php artisan migrate:freshsaben wektu tes ditindakake.

Sampeyan duwe rong pilihan: nggawe database kapisah kanthi fisik utawa nggunakake database SQLite ing memori. Loro-lorone dikonfigurasi ing file phpunit.xmldiwenehake kanthi gawandefinita karo Laravel. Khusus, sampeyan butuh bagean iki:

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

Waca DB_CONNECTIONDB_DATABASEendi sing dikomentari? Yen sampeyan duwe SQLite ing server sampeyan, tumindak sing paling gampang yaiku mbusak komentar baris kasebut lan tes sampeyan bakal nglawan database ing memori kasebut.

Ing tes iki, kita ngomong yen pangguna wis kasil diotentikasi lan dialihake menyang homepage sing bener, nanging kita uga bisa nguji data nyata ing basis data.

Saliyane kode iki:

$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);

Kita uga bisa nggunakake pratelan tes basis data lan nindakake kaya iki:

$this->assertDatabaseCount('users', 1);
 
// Or...
$this->assertDatabaseHas('users', [
    'email' => 'test@example.com',
]);

Tuladha kaca Login

Ayo saiki ndeleng conto liyane saka kaca Login karo 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();
    }
}

Iku babagan formulir login. Logikane padha karo registrasi, ta? Nanging telung cara tinimbang loro, mula iki minangka conto kanggo nguji skenario sing apik lan ala. Dadi, logika umum yaiku sampeyan kudu nyoba loro kasus kasebut: nalika kedadeyan lan nalika gagal.

newsletter inovasi
Aja kantun warta paling penting babagan inovasi. Mlebu kanggo nampa wong-wong mau liwat email.

Uga, apa sing sampeyan deleng ing tes iki yaiku panggunaan Pabrik Database : Laravel nggawe pangguna palsu ( maneh, ing database test dianyari Panjenengan ) lan banjur nyoba mlebu, kanthi kredensial sing bener utawa salah.

Maneh, Laravel ngasilake pra pabrikdefinita karo data palsu kanggo Usermodel, njaba kothak.

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),
        ];
    }
}

Sampeyan ndeleng, pirang-pirang perkara sing disiapake dening Laravel dhewe, mula bakal gampang kanggo miwiti nyoba?

Dadi yen kita eksekusi php artisan testsawise nginstal Laravel Breeze, kita kudu ndeleng kaya iki:

 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

Tes fungsional dibandhingake karo tes unit lan liya-liyane

Sampeyan wis ndeleng subfolder tests/Feature e tests/Unit ?. 

Apa bedane? 

Sacara global, ing njaba ekosistem Laravel/PHP, ana sawetara jinis tes otomatis. Sampeyan bisa nemokake istilah kaya:

  • Tes unit
  • Tes fitur
  • Tes Integrasi
  • Tes fungsional
  • Pengujian end-to-end
  • Tes ditampa
  • Tes kumelun
  • lsp.

Kayane rumit, lan bedane nyata ing antarane jinis tes kasebut kadhangkala kabur. Pramila Laravel nyederhanakake kabeh istilah sing mbingungake lan diklompokake dadi loro: unit / fitur.

Cukup, tes fitur nyoba nglakokake fungsi nyata aplikasi sampeyan: entuk URL, nelpon API, niru prilaku sing tepat kaya ngisi formulir. Tes fitur biasane nindakake operasi sing padha utawa padha kaya sing bakal ditindakake pangguna proyek, kanthi manual, ing urip nyata.

Tes unit duwe rong makna. Umumé, sampeyan bisa nemokake manawa tes otomatis diarani "uji coba unit" lan kabeh proses bisa diarani "uji coba unit". Nanging ing konteks fungsi versus unit, proses iki babagan nguji unit kode non-umum tartamtu, kanthi kapisah. Contone, sampeyan duwe kelas Laravel kanthi cara ngetung soko, kaya total rega pesenan kanthi paramèter. Mula, tes unit bakal nyatakake manawa asil sing bener bakal bali saka metode kasebut (unit kode), kanthi paramèter sing beda.

Kanggo ngasilake tes unit, sampeyan kudu nambah gendera:

php artisan make:test OrderPriceTest --unit

Kode sing digawe padha karo tes pra unitdefiSistem Laravel:

class OrderPriceTest extends TestCase
{
    public function test_example()
    {
        $this->assertTrue(true);
    }
}

Nalika sampeyan bisa ndeleng, iku ora ana RefreshDatabase, lan iki salah siji saka defidefinisi test unit paling umum: ora ndemek database, kerjane minangka "kothak ireng", diisolasi saka aplikasi mlaku.

Coba tiru conto sing wis dakcritakake sadurunge, coba bayangake kita duwe kelas layanan OrderPrice.

app/Services/OrderPriceService.php:

class OrderPriceService
{
    public function calculatePrice($productId, $quantity, $tax = 0.0)
    {
        // Some kind of calculation logic
    }
}

Banjur, tes unit bisa katon kaya iki:

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
}

Ing pengalaman pribadi karo proyek Laravel, mayoritas tes yaiku tes Fitur, dudu tes Unit. Pisanan, sampeyan kudu nyoba apa aplikasi sampeyan bisa digunakake, kanthi cara sing bakal digunakake wong nyata.

Sabanjure, yen sampeyan duwe petungan khusus utawa logika sampeyan bisa definire minangka unit, karo paramèter, sampeyan bisa nggawe tes unit khusus kanggo sing.

Kadhangkala, tes nulis mbutuhake ngowahi kode kasebut dhewe lan refactoring supaya luwih "bisa diuji": misahake unit kasebut dadi kelas utawa metode khusus.

Nalika / carane nindakake tes?

Apa gunane iki php artisan test, kapan sampeyan kudu mbukak?

Ana macem-macem pendekatan, gumantung saka alur kerja bisnis sampeyan, nanging umume sampeyan kudu mesthekake yen kabeh tes "ijo" (ie.

Banjur, sampeyan nggarap tugas kanthi lokal, lan yen sampeyan wis rampung, tindakake sawetara tes kanggo mesthekake yen sampeyan ora nglanggar apa-apa. Elinga, kode sampeyan bisa nyebabake bug ora mung ing logika sampeyan nanging uga ora sengaja ngrusak prilaku liyane ing kode wong liya sing wis ditulis ing jaman biyen.

Yen kita njupuk langkah luwih, iku bisa kanggo otomatis akeh samubarang. Kanthi macem-macem alat CI/CD, sampeyan bisa nemtokake tes sing bakal ditindakake nalika ana wong sing nyurung owah-owahan menyang cabang Git tartamtu utawa sadurunge nggabungake kode menyang cabang produksi. Alur kerja sing paling gampang yaiku nggunakake Tindakan Github, aku duwe video kapisah kang mbuktekaken.

Apa sampeyan kudu nyoba?

Ana macem-macem panemu babagan ukuran sing diarani "jangkoan tes": coba saben operasi lan kasus sing bisa ditindakake ing saben kaca, utawa matesi karya menyang bagean sing paling penting.

Nyatane, ing kene aku setuju karo wong sing nuduh tes otomatis njupuk wektu luwih akeh tinimbang menehi keuntungan nyata. Iki bisa kedadeyan yen sampeyan nulis tes kanggo saben rincian. Sing jarene, bisa uga dibutuhake dening proyek sampeyan: pitakonan utama yaiku "apa rega kesalahan potensial".

Ing tembung liyane, sampeyan kudu prioritize efforts testing dening takon pitakonan "Apa sing bakal kelakon yen kode iki gagal?" Yen sistem pembayaran sampeyan duwe kewan omo, bakal langsung mengaruhi bisnis. Dadi yen fungsi peran / ijin sampeyan rusak, iki minangka masalah keamanan sing gedhe.

Aku seneng karo Matt Stauffer ing konferensi: "Sampeyan kudu nyoba prekara-prekara sing, yen gagal, sampeyan bakal dipecat saka pakaryan sampeyan." Mesthi wae sing berlebihan, nanging sampeyan entuk ide: coba dhisik sing penting. Lan banjur fitur liyane, yen sampeyan duwe wektu.

PEST: alternatif anyar kanggo PHPUnit

Kabeh conto ing ndhuwur adhedhasar alat pre-test Laraveldefibengi: PHPUnit . Nanging ing pirang-pirang taun alat liyane wis muncul ing ekosistem lan salah sawijining sing paling populer yaiku PEST . Digawe dening karyawan Laravel resmi Nuno Maduro , tujuane kanggo nyederhanakake sintaksis, nggawe kode nulis kanggo tes luwih cepet.

Ing ngisor hood, mlaku su PHPUnit, minangka lapisan tambahan, mung nyoba nyilikake sawetara bagean sing wis diulangdefinite saka kode PHPUnit.

Ayo katon ing conto. Elinga kelas tes pra fiturdefiapa ing Laravel? Aku bakal ngelingake sampeyan:

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);
    }
}

Apa sampeyan ngerti kaya apa tes sing padha karo PEST?

test('the application returns a successful response')->get('/')->assertStatus(200);

Ya, ONE baris kode lan iku. Dadi, tujuan PEST yaiku mbusak overhead saka:

  • Nggawe kelas lan cara kanggo kabeh;
  • Ekstensi kasus uji;
  • Kanthi ngetrapake tumindak ing garis sing kapisah: ing PEST sampeyan bisa ngubungake bebarengan.

Kanggo ngasilake tes PEST ing Laravel, sampeyan kudu nemtokake gendera tambahan:

php artisan make:test HomepageTest --pest

Nalika nulis iki, PEST cukup populer ing antarane pangembang Laravel, nanging dadi pilihan pribadi sampeyan nggunakake alat tambahan iki lan sinau sintaks, uga cathetan PHPUnit.

BlogInnovazione.it

newsletter inovasi
Aja kantun warta paling penting babagan inovasi. Mlebu kanggo nampa wong-wong mau liwat email.

Artikel anyar

Penerbit lan OpenAI menehi tandha persetujuan kanggo ngatur aliran informasi sing diproses dening Artificial Intelligence

Senin kepungkur, Financial Times ngumumake kesepakatan karo OpenAI. FT menehi lisensi jurnalisme kelas donya…

30 April 2024

Pembayaran Online: Mangkene Kepiye Layanan Streaming Nggawe Sampeyan Mbayar Selawase

Mayuta-yuta wong mbayar layanan streaming, mbayar biaya langganan saben wulan. Umume pendapat yen sampeyan…

29 April 2024

Veeam nduweni dhukungan paling lengkap kanggo ransomware, saka proteksi nganti respon lan pemulihan

Coveware dening Veeam bakal terus nyedhiyakake layanan respon insiden pemerasan cyber. Coveware bakal nawakake kemampuan forensik lan remediasi…

23 April 2024

Revolusi Ijo lan Digital: Kepiye Pangopènan Prediktif Ngowahi Industri Minyak & Gas

Pangopènan prediktif ngrevolusi sektor minyak & gas, kanthi pendekatan inovatif lan proaktif kanggo manajemen pabrik.…

22 April 2024