Saya perlu berperan sebagai penasihat setan dalam pertanyaan ini sedikit karena saya tidak dapat mempertahankannya dengan baik karena kurangnya pengalaman. Inilah kesepakatannya, saya mendapatkan perbedaan konsep antara pengujian unit dan pengujian integrasi. Ketika secara khusus berfokus pada metode kegigihan dan repositori, unit test akan menggunakan tiruan yang mungkin melalui kerangka kerja seperti Moq untuk menegaskan bahwa mengatakan perintah yang dicari dikembalikan seperti yang diharapkan.
Katakanlah saya telah membangun unit test berikut:
[TestMethod]
public void GetOrderByIDTest()
{
//Uses Moq for dependency for getting order to make sure
//ID I set up in 'Arrange' is same one returned to test in 'Assertion'
}
Jadi jika saya mengatur OrderIdExpected = 5
dan objek tiruan saya kembali 5
sebagai ID pengujian saya akan berlalu. Saya mengerti. Saya unit menguji kode untuk memastikan apa yang saya preforms kode mengembalikan objek dan ID yang diharapkan dan bukan sesuatu yang lain.
Argumen yang akan saya dapatkan adalah ini:
"Mengapa tidak lewati saja tes unit dan lakukan tes integrasi? Ini menguji prosedur yang tersimpan di basis data dan kode Anda bersama-sama itu penting. Sepertinya terlalu banyak pekerjaan ekstra untuk memiliki tes unit dan tes integrasi ketika pada akhirnya saya ingin tahu apakah database memanggil dan kodenya berfungsi. Saya tahu tesnya lebih lama, tetapi harus dijalankan dan diuji, jadi sepertinya tidak ada gunanya bagi saya untuk memiliki keduanya. Cukup uji terhadap yang penting. "
Saya dapat mempertahankannya dengan definisi buku teks seperti: "Ya, itu adalah tes integrasi dan kita perlu menguji kode secara terpisah sebagai tes unit dan, yada, yada, yada ..." Ini adalah kasus di mana penjelasan yang murni tentang praktik vs kenyataan kalah. Saya kadang-kadang mengalami hal ini dan jika saya tidak dapat mempertahankan alasan di balik kode pengujian unit yang pada akhirnya bergantung pada dependensi eksternal, maka saya tidak dapat membuktikannya.
Setiap bantuan untuk pertanyaan ini sangat kami hargai, terima kasih!
sumber
Jawaban:
Tes unit dan tes integrasi memiliki tujuan yang berbeda.
Tes unit memverifikasi fungsionalitas kode Anda ... bahwa Anda mendapatkan kembali apa yang Anda harapkan dari metode ketika Anda menyebutnya. Tes integrasi menguji bagaimana kode berperilaku ketika dikombinasikan bersama sebagai suatu sistem. Anda tidak akan mengharapkan tes unit untuk mengevaluasi perilaku sistem, Anda juga tidak akan mengharapkan tes integrasi untuk memverifikasi output spesifik dari metode tertentu.
Tes unit, jika dilakukan dengan benar, lebih mudah diatur daripada tes integrasi. Jika Anda hanya mengandalkan tes integrasi, pengujian Anda akan:
Intinya: Gunakan pengujian integrasi untuk memverifikasi bahwa koneksi antara objek berfungsi dengan baik, tetapi bersandar pada pengujian unit terlebih dahulu untuk memverifikasi persyaratan fungsional.
Semua yang dikatakan, Anda mungkin tidak perlu pengujian unit untuk metode repositori tertentu. Pengujian unit tidak boleh dilakukan dengan metode sepele ; jika semua yang Anda lakukan adalah melewati permintaan untuk objek ke kode yang dihasilkan ORM dan mengembalikan hasilnya, Anda tidak perlu menguji unit itu, dalam kebanyakan kasus; tes integrasi memadai.
sumber
Saya berada di pihak kaum pragmatis. Jangan menguji kode Anda dua kali.
Kami hanya menulis tes integrasi untuk repositori kami. Tes-tes ini hanya tergantung pada pengaturan tes sederhana yang berjalan terhadap database di-memori. Saya pikir mereka memberikan semua yang dilakukan unit test, dan banyak lagi.
sumber
Tes unit memberikan tingkat modularitas yang tidak dapat dilakukan uji integrasi (sesuai desain). Ketika suatu sistem direaktor atau dikomposisi ulang, (dan ini akan terjadi) unit test sering dapat digunakan kembali, sedangkan tes integrasi harus sering ditulis ulang. Tes integrasi yang mencoba melakukan pekerjaan dari sesuatu yang seharusnya ada dalam unit test sering melakukan terlalu banyak, yang membuatnya sulit untuk dipertahankan.
Selain itu, termasuk pengujian unit memiliki manfaat berikut:
Dimungkinkan untuk membagi pekerjaan Anda (dan menerapkan pendekatan KERING) saat menggunakan tes Unit dan Integrasi. Cukup mengandalkan tes unit untuk unit fungsionalitas kecil, dan jangan ulangi logika apa pun yang sudah ada dalam tes unit dalam tes integrasi. Ini akan sering menyebabkan lebih sedikit pekerjaan (dan karenanya kurang bekerja kembali).
sumber
Tes berguna ketika mereka rusak: Secara proaktif atau aktif kembali.
Tes Unit bersifat proaktif dan mungkin merupakan verifikasi fungsional berkelanjutan sementara Tes Integrasi reaktif pada data bertahap / palsu.
Jika sistem yang dipertimbangkan dekat / bergantung pada data lebih dari logika perhitungan, Tes Integrasi harus menjadi lebih penting.
Misalnya, jika kita sedang membangun sistem ETL, tes yang paling relevan adalah seputar data (dipentaskan, dipalsukan, atau hidup). Sistem yang sama akan memiliki beberapa Tes Unit, tetapi hanya seputar validasi, pemfilteran dll.
Pola repositori seharusnya tidak memiliki logika komputasi atau bisnis. Sangat dekat dengan basis data. Tetapi repositori juga dekat dengan logika bisnis yang menggunakannya. Jadi ini adalah pertanyaan untuk mendapatkan KESEIMBANGAN.
Tes Unit dapat menguji BAGAIMANA Repositori berperilaku. Tes Integrasi dapat menguji APA YANG BENAR-BENAR TERJADI ketika repositori dipanggil.
Sekarang, "APA YANG BENAR-BENAR TERJADI" mungkin tampak sangat menarik. Tetapi ini bisa sangat mahal untuk berjalan secara konsisten dan berulang kali. Definisi klasik dari uji getas berlaku di sini.
Jadi sebagian besar waktu, saya hanya merasa cukup baik untuk menulis Tes unit pada objek yang menggunakan repositori. Dengan cara ini kami menguji apakah metode repositori yang tepat dipanggil dan hasil Mocked yang tepat dikembalikan.
sumber
Ada 3 hal terpisah yang perlu diuji: prosedur tersimpan, kode yang memanggil prosedur tersimpan (yaitu kelas repositori Anda), dan konsumen. Tugas repositori adalah menghasilkan kueri dan mengonversi set data yang dikembalikan menjadi objek domain. Ada cukup kode untuk mendukung pengujian unit yang terpisah dari pelaksanaan aktual permintaan dan pembuatan set data.
Jadi (ini adalah contoh yang sangat sederhana):
Kemudian ketika pengujian
OrderRepository
, berikan mockedISqlExecutor
dan periksa bahwa objek yang diuji lulus dalam SQL yang benar (itu tugasnya) dan mengembalikanOrder
objek yang tepat diberikan beberapa dataset hasil (juga diejek). Kemungkinan satu-satunya cara untuk mengujiSqlExecutor
kelas beton adalah dengan tes integrasi, cukup adil, tapi itu kelas pembungkus tipis dan jarang akan pernah berubah, jadi masalah besar.Anda masih harus menguji unit prosedur tersimpan Anda juga.
sumber
Saya dapat mereduksi ini menjadi garis pemikiran yang sangat sederhana: Mendukung unit test karena membantu menemukan bug. Dan lakukan ini secara konsisten karena ketidakkonsistenan menyebabkan kebingungan.
Alasan lebih lanjut berasal dari aturan yang sama yang memandu pengembangan OO karena mereka juga berlaku untuk tes. Misalnya, prinsip tanggung jawab tunggal.
Jika beberapa tes unit tampaknya tidak layak dilakukan, maka mungkin itu pertanda bahwa subjek tersebut sebenarnya tidak layak untuk dimiliki. Atau mungkin fungsinya lebih abstrak dari padanannya, dan tes untuk itu (serta kodenya) dapat diabstraksikan ke tingkat yang lebih tinggi.
Seperti apa pun, ada pengecualian. Dan pemrograman masih agak dari bentuk seni sehingga banyak masalah cukup berbeda untuk menjamin menilai masing-masing untuk pendekatan terbaik.
sumber