Gambaran keseluruhan pengujian unit



Ini bukan panduan tentang karakter apa yang perlu Anda masukkan dalam editor kode untuk mendapatkan tes unit. Ini adalah makanan untuk pikiran, yang harus dikonsumsi sebelum mengambil tindakan ini.

Topik pengujian unit tidak sesederhana kelihatannya. Banyak dari kita pengembang datang ke unit testing di bawah tekanan dari pelanggan, karyawan, kolega, idola mereka, dan sebagainya. Kami dengan cepat memahami nilainya, dan, setelah menyelesaikan persiapan teknis, kami melupakan gambaran umum, jika sama sekali, sama sekali. Pada artikel ini, saya akan membahas secara singkat tentang apa itu pengujian unit, dan apa yang tidak, baik secara umum maupun dalam PHP, dan pada saat yang sama saya akan menjelaskan tempat pengujian unit apa dalam lingkup QA.

Apa itu pengujian?


Sebelum mempelajari tes unit, Anda perlu mempelajari teori pengujian itu sendiri agar tidak membuat kesalahan seperti yang dilakukan oleh penulis dari salah satu kerangka kerja PHP yang paling populer: mereka menunjukkan tes integrasi di situs web mereka dan menyebutnya tes unit. Tidak, Laravel, ini bukan tes unit. Meskipun ini tidak menghentikan saya, saya masih mencintai kerangka ini.

Pengujian perangkat lunak didefinisikan sebagai "penyelidikan yang dilakukan untuk memberikan informasi kepada pihak yang berkepentingan tentang kualitas produk." Ini bertentangan dengan "pengujian perangkat lunak adalah pemborosan anggaran proyek oleh pengembang yang tidak melakukan hal penting dan kemudian meminta lebih banyak waktu dan uang, karena" tidak ada "yang bisa sangat mahal." Tidak ada yang baru di sini.

Inilah sejarah singkat saya untuk menjadi ujian:

  • 1822 - Mesin perbedaan (Charles Babbage).
  • 1843 - Mesin analitik (Ada Lovelace).
  • 1878 - Edison memperkenalkan istilah "bug."
  • 1957 - Pengujian dan debugging program (Charles Baker).
  • 1958 - Tim pengujian perangkat lunak pertama (Gerald Weinberg).
  • 1968 - Crisis PO (Friedrich Bauer).
  • 1970-an - Model air terjun, model relasional, dekomposisi, analisis kritis ( Walkthrough ), desain dan inspeksi kode, kualitas dan metrik, pola desain.
  • 1980-an - Analisis CRUD, arsitektur sistem, autotesting, model-V, keandalan, biaya kualitas, metode penggunaan, pola desain OOP.
  • 1990-an - Scrum, pengujian kegunaan, MoSCoW, pengujian heuristik, otomatisasi dan pengujian perangkat lunak.

Jika Anda berhubungan dengan generasi milenium seperti saya, Anda mungkin kagum bahwa tim penguji ada PANJANG sebelum Anda dilahirkan. Berhentilah sejenak, tarik napas, hembuskan napas, tenang.
Sejarah menunjukkan bagaimana jenis pengujian yang dianggap "cukup baik" untuk pihak yang berkepentingan berubah dari waktu ke waktu. Perkiraan fase yang dipandu selama pengujian:

  • ... - 1956 debugging
  • 1957 - 1978 Demonstrasi
  • 1979 - 1982 kehancuran
  • Perkiraan 1983 - 1987
  • 1988 - ... pencegahan

Oleh karena itu, pengujian unit diperlukan untuk mencegah perbedaan antara proyek dan implementasi.

Apa sebenarnya pengujian itu?


Ada beberapa klasifikasi pengujian perangkat lunak. Untuk lebih memahami tempat pengujian unit, saya hanya akan menyebutkan pendekatan yang paling luas.

Tes adalah: statis dan dinamis, "kotak" (kotak putih, kotak hitam, kotak abu-abu), level dan tipe. Setiap pendekatan menggunakan kriteria klasifikasi yang berbeda.

Pengujian statis dan dinamis


Pengujian statis dilakukan tanpa eksekusi kode. Ini termasuk proofreading, verifikasi, revisi kode (ketika mengamati pekerjaan pemrograman pasangan lain), analisis kritis, inspeksi, dan sebagainya.

Pengujian dinamis untuk mendapatkan hasil yang benar membutuhkan eksekusi kode. Misalnya, untuk tes unit , integrasi, sistem, penerimaan, dan tes lainnya. Artinya, pengujian dilakukan dengan menggunakan data dinamis, input dan output.

Pendekatan kotak


Menurut pendekatan ini, semua pengujian perangkat lunak dibagi menjadi tiga jenis kotak:

  • Pengujian kotak putih memverifikasi struktur dan modul internal, mengabaikan fungsionalitas yang diharapkan untuk pengguna akhir. Ini bisa berupa pengujian API, injeksi kesalahan, pengujian unit , pengujian integrasi.
  • Pengujian black box lebih tertarik pada apa yang dilakukan perangkat lunak, dan bukan bagaimana melakukannya. Ini berarti bahwa penguji tidak diharuskan untuk memahami objek pengujian atau memahami cara kerjanya di bawah tenda. Jenis pengujian ini ditujukan untuk pengguna akhir, pengalaman mereka berinteraksi dengan antarmuka yang terlihat. Kotak hitam meliputi pengujian berbasis model, pengujian penggunaan, tabel transisi negara, pengujian spesifikasi, dll.
  • Pengujian tipe " kotak abu-abu " dirancang dengan pengetahuan tentang algoritma perangkat lunak dan struktur data (kotak putih), tetapi dilakukan di tingkat pengguna (kotak hitam). Ini termasuk pengujian regresi dan pengujian pola.

Sekarang, untuk membingungkan Anda, saya akan mengatakan bahwa pengujian unit juga dapat berlaku untuk "kotak hitam", karena Anda dapat memahami modul yang sedang diuji, tetapi tidak untuk keseluruhan sistem. Meskipun bagi saya itu masih merupakan "kotak putih", dan saya sarankan Anda setuju dengan ini.

Tingkat tes


Jumlah mereka bervariasi, biasanya dalam kisaran 4 hingga 6, dan mereka semua berguna. Nama-nama juga bisa berbeda, tergantung pada budaya yang diadopsi oleh perusahaan, Anda mungkin tahu tes "integrasi" sebagai "fungsional", tes "sistem" sebagai "otomatis", dan sebagainya. Untuk kesederhanaan, saya akan menjelaskan 5 level:

  1. Pengujian unit
  2. Pengujian Integrasi.
  3. Menguji antarmuka komponen.
  4. Pengujian sistem.
  5. Pengujian penerimaan operasional.

Pengujian unit menguji fungsionalitas potongan kode tertentu, biasanya satu fungsi pada satu waktu. Pengujian integrasi memeriksa antarmuka antara komponen sehingga modul yang dirakit bersama membentuk sistem yang berfungsi sebagaimana dimaksud. Ini adalah poin penting, karena sejumlah besar tes, yang disebut tes unit, sebenarnya adalah tes integrasi, dan pengembang menganggapnya sebagai modul. Jika Anda bermaksud menggunakan beberapa modul - ini sedang menguji integrasi di antara mereka, dan bukan modul itu sendiri. Antarmuka komponen pengujian memeriksa data yang ditransfer antara modul yang berbeda. Sebagai contoh, kami menerima data dari modul 1 - diperiksa - ditransfer ke modul 2 - diperiksa. Pengujian sistem adalah pengujian ujung-ke-ujung untuk memverifikasi kepatuhan dengan semua persyaratan. Pengujian penerimaan operasional dilakukan untuk memverifikasi kesiapan operasional. Itu tidak fungsional, hanya kemudahan servis dari layanan yang diperiksa, apakah ada subsistem yang merusak lingkungan dan layanan lainnya.

Jenis Pengujian


Setiap jenis pengujian, terlepas dari levelnya, juga dapat dibagi menjadi jenis lain. Ada lebih dari 20 tipe umum. Yang paling umum:

  • Pengujian regresi .
  • Tes penerimaan.
  • Pengujian asap
  • Uat
  • Pengujian yang merusak .
  • Pengujian kinerja.
  • Pengujian berkelanjutan .
  • Pengujian kegunaan.
  • Pengujian keamanan.

Dari namanya jelas mengapa pengujian jenis ini atau itu dimaksudkan. Bold adalah unit test dalam PHP. Jika Anda benar-benar ingin, maka Anda dapat menerapkan masing-masing persyaratan ini ke unit testing. Namun, variasi utama dari tes unit adalah tes regresi, yang memeriksa apakah semua modul sistem dieksekusi dengan benar setelah membuat perubahan pada kode.

Sekarang Anda tahu bahwa tes unit bersifat dinamis, termasuk dalam kelas "kotak putih", dilakukan pada level modul, merupakan tes regresi, tetapi tes modular dapat dipahami sebagai banyak jenis tes. Jadi apa sebenarnya tes unit?

Apa itu pengujian unit?


Model-V adalah representasi grafis dari tingkat di atas, jenis dan tujuannya dalam siklus hidup pengembangan perangkat lunak.



Setelah memeriksa dan menyetujui persyaratan terperinci untuk produk, ketika mereka mulai menulis kode, tes unit menjadi garis pertahanan pertama terhadap segala ketidakkonsistenan. Oleh karena itu, perusahaan yang memahami apa yang mereka lakukan memaksa pengembang untuk menggunakan tes unit atau bahkan TDD, karena jauh lebih murah untuk memperbaiki bug pada tahap awal daripada yang lebih baru.

Dan ini adil. Tes unit memiliki banyak keunggulan. Mereka adalah:

  • Isolasi setiap bagian dari program dan periksa kebenarannya.
  • Bantu mendeteksi masalah sejak dini.
  • Mereka membuat pengembang berpikir dalam hal input, output, dan kondisi yang salah.
  • Mereka memberikan kode tampilan yang mudah untuk pengujian, memfasilitasi refactoring di masa depan.
  • Sederhanakan integrasi Modul kerja (!).
  • Ganti sebagian dokumentasi teknis.
  • Terpaksa memisahkan antarmuka dari implementasi.
  • Mereka membuktikan bahwa kode modul berfungsi seperti yang diharapkan (setidaknya secara matematis).
  • Dapat digunakan sebagai suite uji regresi tingkat rendah.
  • Menunjukkan kemajuan dalam integrasi sistem yang tidak lengkap.
  • Kurangi biaya perbaikan bug (dengan TDD - bahkan lebih).
  • Mereka memungkinkan Anda untuk meningkatkan arsitektur aplikasi dengan menentukan tanggung jawab modul.
  • Jika Anda dapat mengujinya, maka Anda dapat melampirkan ke sistem Anda.
  • Pengujian unit MENYENANGKAN!

Namun, ada beberapa batasan yang Anda pikirkan, mungkin ketika membaca daftar ini:

  • Pengujian unit tidak menangkap kesalahan integrasi.
  • Setiap ekspresi Boolean membutuhkan setidaknya dua tes, dan jumlahnya tumbuh dengan cepat.
  • Tes unit sama buggy dengan kode yang mereka uji.
  • Menghubungkan tes ke beberapa kerangka kerja atau pustaka tertentu dapat membatasi alur kerja.
  • Sebagian besar tes ditulis setelah pengembangan selesai. Menyedihkan. Gunakan TDD!
  • Mungkin setelah sedikit refactoring, sistem akan bekerja seperti sebelumnya, tetapi pengujiannya akan gagal.
  • Biaya pengembangan terus meningkat.
  • Human error: mengomentari tes yang rusak.
  • Human error: menambahkan solusi ke kode khusus untuk lulus tes unit.

Yang terakhir paling banyak membunuh saya. (Hampir) di setiap proyek, langsung dalam kode sumber aplikasi yang bekerja, saya menemukan baris seperti "jika itu adalah unit test, memuat database SQLite pengganti, jika tidak memuat database lain", atau "jika itu adalah unit test, jangan kirim email, jika tidak kirim ”, dan seterusnya. Jika aplikasi Anda memiliki arsitektur yang buruk, jangan berpura-pura bahwa Anda dapat memperbaiki perangkat lunak yang buruk dengan tes lulus yang baik, itu tidak akan menjadi lebih baik dari ini.

Saya sering berdiskusi dengan kolega dan klien apakah unit test yang bagus itu. Dia:

  • Cepat
  • Otomatis.
  • Sepenuhnya mengontrol semua dependensinya.
  • Dapat diandalkan: dapat diluncurkan dalam urutan apa pun, terlepas dari tes lainnya.
  • Ini hanya dapat dijalankan di memori (tidak ada interaksi dengan database, baca / tulis dalam sistem file).
  • Selalu mengembalikan hasil tunggal.
  • Nyaman untuk membaca dan iringan.
  • Tidak menguji konfigurasi SUT (sistem sedang diuji).
  • Memiliki TUNGGAL TUNGGAL yang jelas.
  • Itu bernama baik (dan cukup dimengerti untuk menghindari debugging hanya demi mencari tahu apa yang gagal).

Bagi mereka yang menyeringai setelah membaca "otomatis": Saya tidak bermaksud mengintegrasikan PHPUnit atau JUnit ke dalam pipa CI. Intinya adalah bahwa jika Anda mengubah kode, simpan dan jangan tahu apakah modul lulus tes mereka, maka mereka tidak otomatis, tetapi harus. Pilihan yang menang adalah pelacakan file.

Apa yang harus dikenai pengujian unit?


Dalam sistem normal, tes unit perlu ditulis untuk:

  • Modul - bagian yang tidak dapat dipisahkan dari sistem yang melakukan satu tugas (fungsi, metode, kelas).
  • Metode publik.
  • Metode yang dilindungi, tetapi hanya dalam kasus yang jarang dan ketika tidak ada yang melihat.
  • Bug dan perbaikannya.

Definisi uji unit tergantung pada pengembang yang menulis kode. Dalam PHP, ini hampir selalu merupakan metode atau fungsi kelas, karena itu adalah bagian dari perangkat lunak yang tidak terpisahkan yang masuk akal sendiri . Beberapa kali saya melihat bagaimana pengembang menggunakan array miniclasses satu metode sebagai modul tunggal. Ini masuk akal jika fungsionalitas minimal membutuhkan banyak objek.

Jadi Anda sendiri dapat menentukan modul apa yang cocok untuk Anda. Atau Anda dapat menguji metode satu per satu, membuat hidup lebih mudah bagi pria yang kemudian akan bekerja dengan kode tersebut.

Jika Anda tidak melakukan pengujian unit, saya mengusulkan untuk melakukan ini setelah bug besar berikutnya. Periksa metode mana yang akan dikaitkan, tulis tes gagal dengan argumen dan hasil yang benar, perbaiki bug, jalankan uji unit lagi. Jika dilewatkan, Anda dapat yakin bahwa bug ini harus diperbaiki untuk terakhir kalinya (dengan mempertimbangkan skenario input spesifik Anda).

Pendekatan ini membuat pengujian unit lebih mudah dipahami. Analisis setiap metode secara terpisah. Penyedia data dapat membantu menentukan input dan output untuk setiap skenario yang mungkin muncul di pikiran Anda, jadi apa pun yang terjadi, Anda akan tahu apa yang diharapkan.

Apa yang TIDAK perlu diuji


Agak sulit untuk menentukan bahwa Anda tidak perlu menguji. Saya mencoba menyusun daftar elemen yang tidak perlu dikenai pengujian unit:

  • Fungsionalitas di luar ruang lingkup modul (!)
  • Integrasi modul dengan modul lain (!)
  • Perilaku yang tidak diinsulasi (dependensi yang tidak dapat digerakkan, database nyata, jaringan)
  • Metode pribadi yang aman.
  • Metode statis.
  • Perpustakaan eksternal.
  • Kerangka kerja Anda.

Saya yakin bahwa pengujian unit tidak boleh diterapkan pada hal-hal di atas, kecuali untuk metode statis. Saya suka berargumen bahwa statis, pada dasarnya, berarti proseduralitas, dan dalam banyak kasus proseduralitas bersifat global. Jika metode statis memanggil metode statis lain, maka ketergantungan ini tidak dapat ditimpa. Ini berarti bahwa Anda sekarang menguji secara terpisah. Dan kemudian ini bukan lagi pengujian unit. Di sisi lain, ini adalah bagian dari kode yang dapat hidup sendiri, ia memiliki tujuan, dan perlu diuji untuk memastikan bahwa tidak peduli bagian mana dari sistem bodoh ini yang diuji bagian dari kode panggilan, ia tidak akan rusak. Oleh karena itu, saya percaya bahwa Anda dapat menguji metode statis jika Anda yakin bahwa hasil tes Anda tidak dapat diubah oleh tes lain, dan bahwa bahasa atau kerangka kerja memungkinkan Anda untuk menguji secara asli.

Bagaimana cara menulis unit test?


  • Tulis kode yang sesuai untuk pengujian unit, lalu ujilah.
  • Tulis kode yang sesuai untuk pengujian unit, lalu ujilah.
  • Tulis kode yang sesuai untuk pengujian unit, lalu ujilah.

Jika "maka uji" itu tidak cukup, maka laracasts.com memiliki video yang sangat bagus tentang pengujian unit PHP. Ada banyak situs yang didedikasikan untuk tugas yang sama dalam bahasa lain. Saya tidak melihat alasan untuk menjelaskan bagaimana saya melakukan pengujian unit, karena alat berubah cukup cepat, dan ketika Anda membaca teks ini, saya dapat beralih dari PHPUnit ke Kahlan. Atau tidak. Siapa tahu.

Tetapi untuk menjawab pertanyaan pertama (bagaimana menulis kode yang cocok untuk pengujian unit) jauh lebih mudah, dan situasinya tidak banyak berubah seiring waktu:

  • PADAT
  • KERING
  • Kurangnya kata kunci baru di konstruktor.
  • Tidak adanya loop dalam konstruktor (dan transisi, jika ditentukan).
  • Kurangnya metode statis, parameter, kelas.
  • Kurangnya metode setup (): objek harus diinisialisasi penuh setelah konstruksi.
  • Kurangnya singleton (status global) dan antipattern lain yang tidak dapat diuji.
  • Kurangnya objek mahakuasa (objek Tuhan).
  • Kurangnya kelas dengan fungsionalitas campuran (kelas perhatian campuran).
  • Tidak ada dependensi tersembunyi.

Sekarang, dengan mengetahui apa itu unit test dan apa yang bukan, apa yang Anda butuhkan dan apa yang tidak perlu Anda uji, tempat tes apa yang diambil dalam siklus hidup pengembangan perangkat lunak, akan lebih mudah bagi Anda untuk mengimplementasikannya. Masih menemukan kerangka atau pustaka yang Anda sukai. Jika ragu, ambil kerangka / bahasa standar de facto.

Kesimpulannya: unit test sangat penting bagi pengembang dan bisnis. Mereka perlu ditulis, ada metode terbukti yang akan membantu Anda dengan mudah menutupi modul dengan tes, terutama dengan menyiapkan modul itu sendiri. Tetapi semua teknik ini tidak masuk akal tanpa sepengetahuan teori pengujian yang dijelaskan dalam artikel ini. Anda harus dapat membedakan tes unit dari tes jenis lain. Dan ketika Anda memiliki pemahaman yang jelas di kepala Anda, maka akan menjadi lebih mudah bagi Anda untuk menulis tes.

Source: https://habr.com/ru/post/id412695/


All Articles