Terkait pengujian otomatis atau pengujian unit, dalam bahasa pemrograman apa pun, ada dua pendapat yang berlawanan:
Jadi, dengan artikel ini kami akan mencoba meyakinkan yang pertama, terutama dengan menunjukkan betapa mudahnya memulai pengujian otomatis di Laravel.
Pertama mari kita bicara tentang "mengapa", dan kemudian mari kita lihat beberapa contoh bagaimana caranya.
Tes otomatis menjalankan bagian kode dan melaporkan kesalahan apa pun. Itulah cara paling sederhana untuk menggambarkannya. Bayangkan meluncurkan fitur baru di sebuah aplikasi, lalu asisten robot pribadi akan menguji fitur baru tersebut secara manual, sekaligus menguji apakah kode baru tersebut tidak merusak fitur lama.
Inilah keuntungan utamanya: menguji ulang semua fitur secara otomatis. Ini mungkin tampak seperti pekerjaan ekstra, tetapi jika Anda tidak menyuruh “robot” untuk melakukannya, sebaiknya kita melakukannya secara manual, bukan?
Atau fitur baru dapat dirilis tanpa menguji apakah fitur tersebut berfungsi, dengan harapan pengguna akan melaporkan bug.
Tes otomatis dapat memberi kita beberapa keuntungan:
Coba bayangkan aplikasi Anda dalam satu atau dua tahun, dengan pengembang baru di tim yang tidak mengetahui kode yang ditulis pada tahun-tahun sebelumnya, atau bahkan cara mengujinya.
Untuk melakukan yang pertama pengujian otomatis di Laravel, Anda tidak perlu menulis kode apa pun. Ya, Anda membacanya dengan benar. Semuanya sudah dikonfigurasi dan disiapkan pada pra-instalasidefinite dari Laravel, termasuk contoh dasar pertama.
Anda dapat mencoba menginstal proyek Laravel dan segera menjalankan pengujian pertama:
laravel new project
cd project
php artisan test
Ini akan menjadi hasil di konsol Anda:
Jika kita melihat pada bagian sebelumnyadefimalam Laravel /tests
, kami memiliki dua file:
tes/Fitur/ExampleTest.php :
class ExampleTest extends TestCase
{
public function test_the_application_returns_a_successful_response()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
Anda tidak perlu mengetahui sintaks apa pun untuk memahami apa yang terjadi di sini: muat halaman beranda dan periksa apakah kode status HTTP
è "200 OK
".
Juga dikenal sebagai nama metode test_the_application_returns_a_successful_response()
menjadi teks yang dapat dibaca ketika Anda melihat hasil tes, cukup dengan mengganti simbol garis bawah dengan spasi.
tes/Unit/ExampleTest.php :
class ExampleTest extends TestCase
{
public function test_that_true_is_true()
{
$this->assertTrue(true);
}
}
Tampaknya agak tidak ada gunanya, memeriksa apakah ini benar?
Kami akan berbicara secara khusus tentang pengujian unit nanti. Untuk saat ini, Anda perlu memahami apa yang umumnya terjadi di setiap pengujian.
/tests
adalah kelas PHP yang memperluas TestCase Unit PHPSecara struktural, hanya itu yang perlu Anda ketahui, sisanya bergantung pada hal-hal yang ingin Anda uji.
Untuk menghasilkan kelas pengujian kosong, cukup jalankan perintah ini:
php artisan make:test HomepageTest
File dibuat 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);
}
}
Sekarang mari kita lihat apa yang terjadi jika pernyataan pengujian tidak memberikan hasil yang diharapkan.
Mari kita ubah contoh tes menjadi ini:
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);
}
}
Dan sekarang, jika kita menjalankan perintah php artisan test
lagi:
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
Ada dua tes yang gagal, ditandai sebagai GAGAL, dengan penjelasan di bawah dan panah yang menunjuk ke baris tes yang gagal. Kesalahan ditunjukkan dengan cara ini.
Misalkan kita mempunyai sebuah formulir dan kita perlu menguji berbagai kasus: kita memeriksa apakah formulir tersebut gagal dengan data yang tidak valid, kita memeriksa apakah formulir tersebut berhasil dengan input yang benar, dll.
Paket starter resmi oleh Laravel Breeze termasuk saya menguji fungsionalitas di dalamnya. Mari kita lihat beberapa contoh dari sana:
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);
}
}
Di sini kita mempunyai dua pengujian dalam satu kelas, karena keduanya terkait dengan formulir pendaftaran: satu memeriksa apakah formulir dimuat dengan benar dan yang lain memeriksa apakah pengiriman berfungsi dengan baik.
Mari kita kenali dua metode lagi untuk memverifikasi hasil, dua pernyataan lagi: $this->assertAuthenticated()
e $response->assertRedirect()
. Anda dapat memeriksa semua pernyataan yang tersedia di dokumentasi resmi Unit PHP e Respon Laravel . Perhatikan bahwa beberapa pernyataan umum muncul mengenai subjek ini $this
, sementara yang lain memeriksa secara spesifik $response
dari panggilan rute.
Hal penting lainnya adalah use RefreshDatabase;
pernyataan, dengan coretan, disisipkan di atas kelas. Hal ini diperlukan ketika tindakan pengujian dapat mempengaruhi database, seperti dalam contoh ini, logging menambahkan entri baru ke dalam database users
tabel basis data. Untuk ini, Anda harus membuat database pengujian terpisah yang akan diperbarui php artisan migrate:fresh
setiap kali tes dijalankan.
Anda memiliki dua opsi: membuat database terpisah secara fisik atau menggunakan database SQLite dalam memori. Keduanya dikonfigurasi dalam file phpunit.xml
disediakan secara defaultdefinita dengan LARAVEL. Secara khusus, Anda memerlukan bagian ini:
<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>
Lihat DB_CONNECTION
e DB_DATABASE
mana yang dikomentari? Jika Anda memiliki SQLite di server Anda, tindakan paling sederhana adalah dengan menghapus komentar pada baris tersebut dan pengujian Anda akan dijalankan terhadap database dalam memori tersebut.
Dalam pengujian ini kami mengatakan bahwa pengguna berhasil diautentikasi dan diarahkan ke beranda yang benar, namun kami juga dapat menguji data aktual di database.
Selain kode ini:
$this->assertAuthenticated();
$response->assertRedirect(RouteServiceProvider::HOME);
Kita juga bisa menggunakan pernyataan pengujian database dan lakukan sesuatu seperti ini:
$this->assertDatabaseCount('users', 1);
// Or...
$this->assertDatabaseHas('users', [
'email' => 'test@example.com',
]);
Sekarang mari kita lihat contoh lain halaman Login dengan 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();
}
}
Ini tentang formulir login. Logikanya mirip dengan registrasi kan? Namun tiga metode, bukan dua, jadi ini adalah contoh pengujian skenario baik dan buruk. Jadi, logika umumnya adalah Anda harus menguji kedua kasus tersebut: kapan semuanya berjalan baik dan kapan gagal.
Juga, apa yang Anda lihat dalam tes ini adalah penggunaan Pabrik Basis Data : Laravel membuat pengguna palsu ( sekali lagi, pada database pengujian Anda yang diperbarui ) dan kemudian mencoba masuk, dengan kredensial yang benar atau salah.
Sekali lagi, Laravel menghasilkan pra pabrikdefinita dengan data palsu untuk itu User
model, di luar kotak.
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),
];
}
}
Soalnya, berapa banyak hal yang disiapkan oleh Laravel sendiri, lalu mudahkah kita memulai pengujiannya?
Jadi jika kita mengeksekusi php artisan test
setelah menginstal Laravel Breeze, kita akan melihat sesuatu seperti ini:
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
Anda telah melihat subfoldernya tests/Feature
e tests/Unit
?.
Apa perbedaan di antara keduanya?
Secara global, di luar ekosistem Laravel/PHP, terdapat beberapa jenis pengujian otomatis. Anda dapat menemukan istilah seperti:
Kedengarannya rumit, dan perbedaan sebenarnya antara jenis tes ini terkadang tidak jelas. Itu sebabnya Laravel menyederhanakan semua istilah yang membingungkan ini dan mengelompokkannya menjadi dua: unit/fitur.
Sederhananya, pengujian fitur mencoba menjalankan fungsionalitas sebenarnya dari aplikasi Anda: mendapatkan URL, memanggil API, meniru perilaku persis seperti mengisi formulir. Pengujian fitur biasanya melakukan operasi yang sama atau serupa seperti yang dilakukan pengguna proyek mana pun, secara manual, di kehidupan nyata.
Tes unit memiliki dua arti. Secara umum, Anda mungkin menemukan bahwa pengujian otomatis apa pun disebut “pengujian unit” dan keseluruhan prosesnya dapat disebut “pengujian unit”. Namun dalam konteks fungsionalitas versus unit, proses ini adalah tentang pengujian unit kode non-publik tertentu, secara terpisah. Misalnya, Anda memiliki kelas Laravel dengan metode yang menghitung sesuatu, seperti total harga pesanan dengan parameter. Oleh karena itu, pengujian unit akan menyatakan apakah hasil yang benar dikembalikan dari metode tersebut (unit kode), dengan parameter yang berbeda.
Untuk menghasilkan pengujian unit, Anda perlu menambahkan tanda:
php artisan make:test OrderPriceTest --unit
Kode yang dihasilkan sama dengan tes pra unitdefiSistem Laravel:
class OrderPriceTest extends TestCase
{
public function test_example()
{
$this->assertTrue(true);
}
}
Seperti yang Anda lihat, itu tidak ada RefreshDatabase
, dan ini adalah salah satunya defidefinisi pengujian unit yang paling umum: tidak menyentuh database, berfungsi sebagai "kotak hitam", diisolasi dari aplikasi yang sedang berjalan.
Coba tiru contoh yang saya sebutkan tadi, bayangkan kita mempunyai kelas jasa OrderPrice
.
app/Services/OrderPriceService.php:
class OrderPriceService
{
public function calculatePrice($productId, $quantity, $tax = 0.0)
{
// Some kind of calculation logic
}
}
Kemudian, pengujian unit akan terlihat seperti ini:
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
}
Dalam pengalaman pribadi saya dengan proyek Laravel, sebagian besar pengujian adalah pengujian Fitur, bukan pengujian Unit. Pertama, Anda perlu menguji apakah aplikasi Anda berfungsi, seperti cara orang menggunakannya.
Selanjutnya, jika Anda memiliki perhitungan atau logika khusus, Anda bisa definire sebagai sebuah unit, dengan parameter, Anda dapat membuat pengujian unit khusus untuk itu.
Terkadang, menulis tes memerlukan modifikasi kode itu sendiri dan memfaktorkannya ulang agar lebih “dapat diuji”: memisahkan unit ke dalam kelas atau metode khusus.
Apa sebenarnya kegunaan ini php artisan test
, kapan sebaiknya Anda menjalankannya?
Ada beberapa pendekatan yang berbeda, bergantung pada alur kerja bisnis Anda, namun umumnya Anda perlu memastikan bahwa semua pengujian bersifat “hijau” (yaitu bebas kesalahan) sebelum memasukkan perubahan kode akhir ke repositori.
Kemudian, Anda mengerjakan tugas Anda secara lokal, dan ketika Anda merasa sudah selesai, jalankan beberapa tes untuk memastikan Anda tidak merusak apa pun. Ingat, kode Anda mungkin menyebabkan bug tidak hanya pada logika Anda tetapi juga secara tidak sengaja merusak beberapa perilaku lain dalam kode orang lain yang ditulis sejak lama.
Jika kita melangkah lebih jauh, otomatisasi dapat dilakukan banyak hal-hal. Dengan berbagai alat CI/CD, Anda dapat menentukan pengujian yang akan dijalankan setiap kali seseorang melakukan perubahan ke cabang Git tertentu atau sebelum menggabungkan kode ke cabang produksi. Alur kerja paling sederhana adalah menggunakan Github Actions, yang saya punya video terpisah yang membuktikannya.
Ada perbedaan pendapat mengenai seberapa besar apa yang disebut “cakupan pengujian” seharusnya: coba setiap kemungkinan operasi dan kasus di setiap halaman, atau batasi pekerjaan pada bagian yang paling penting.
Faktanya, saya setuju dengan orang-orang yang menuduh pengujian otomatis memakan waktu lebih lama daripada memberikan manfaat sebenarnya. Ini bisa terjadi jika Anda menulis tes untuk setiap detail. Meskipun demikian, ini mungkin diperlukan oleh proyek Anda: pertanyaan utamanya adalah “berapa harga dari potensi kesalahan”.
Dengan kata lain, Anda perlu memprioritaskan upaya pengujian Anda dengan mengajukan pertanyaan “Apa yang akan terjadi jika kode ini gagal?” Jika sistem pembayaran Anda mengalami bug, maka akan berdampak langsung pada bisnis. Jadi jika fungsi peran/izin Anda rusak, ini adalah masalah keamanan yang sangat besar.
Saya suka bagaimana Matt Stauffer mengatakannya di sebuah konferensi: “Anda harus terlebih dahulu menguji hal-hal yang, jika gagal, akan membuat Anda dipecat dari pekerjaan Anda.” Tentu saja itu berlebihan, tetapi Anda mengerti maksudnya: cobalah hal-hal penting terlebih dahulu. Dan fitur lainnya, jika Anda punya waktu.
Semua contoh di atas didasarkan pada alat pra-pengujian Laraveldefimalam: Unit PHP . Namun selama bertahun-tahun, alat lain telah muncul di ekosistem dan salah satu alat terbaru yang populer adalah HAMA . Dibuat oleh karyawan resmi Laravel Nuno Maduro , bertujuan untuk menyederhanakan sintaksis, membuat penulisan kode untuk pengujian menjadi lebih cepat.
Di bawah tenda, ia berjalan su PHPUnit, sebagai lapisan tambahan, hanya mencoba meminimalkan beberapa bagian yang berulangdefiakhir dari kode PHPUnit.
Mari kita lihat sebuah contoh. Ingat kelas tes pra fiturdefinited di Laravel? Aku akan mengingatkanmu:
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);
}
}
Tahukah Anda seperti apa tes yang sama dengan PEST?
test('the application returns a successful response')->get('/')->assertStatus(200);
Ya, SATU baris kode dan hanya itu. Jadi, tujuan PEST adalah menghilangkan overhead dari:
Untuk menghasilkan pengujian PEST di Laravel, Anda perlu menentukan flag tambahan:
php artisan make:test HomepageTest --pest
Saat tulisan ini dibuat, PEST cukup populer di kalangan pengembang Laravel, namun terserah pada preferensi pribadi Anda apakah akan menggunakan alat tambahan ini dan mempelajari sintaksnya, serta catatan PHPUnit.
BlogInnovazione.it
Operasi oftalmoplasti menggunakan penampil komersial Apple Vision Pro dilakukan di Poliklinik Catania…
Mengembangkan keterampilan motorik halus melalui mewarnai mempersiapkan anak untuk keterampilan yang lebih kompleks seperti menulis. Mewarnai…
Sektor angkatan laut adalah kekuatan ekonomi global sejati, yang telah menuju pasar 150 miliar...
Senin lalu, Financial Times mengumumkan kesepakatan dengan OpenAI. FT melisensikan jurnalisme kelas dunianya…