Perbedaan utama, bagi saya, adalah bahwa tes integrasi mengungkapkan jika suatu fitur berfungsi atau rusak, karena mereka menekankan kode dalam skenario yang mendekati kenyataan. Mereka memanggil satu atau lebih metode atau fitur perangkat lunak dan menguji apakah mereka bertindak seperti yang diharapkan.
Sebaliknya, tes Unit menguji metode tunggal bergantung pada asumsi (sering salah) bahwa sisa perangkat lunak bekerja dengan benar, karena secara eksplisit mengolok-olok setiap ketergantungan.
Oleh karena itu, ketika uji unit untuk metode yang menerapkan beberapa fitur berwarna hijau, itu tidak berarti fitur tersebut berfungsi.
Katakanlah Anda memiliki metode di suatu tempat seperti ini:
public SomeResults DoSomething(someInput) {
var someResult = [Do your job with someInput];
Log.TrackTheFactYouDidYourJob();
return someResults;
}
DoSomething
sangat penting bagi pelanggan Anda: itu adalah fitur, satu-satunya hal yang penting. Itu sebabnya Anda biasanya menulis spesifikasi Mentimun yang menyatakannya: Anda ingin memverifikasi dan mengkomunikasikan fitur tersebut berfungsi atau tidak.
Feature: To be able to do something
In order to do something
As someone
I want the system to do this thing
Scenario: A sample one
Given this situation
When I do something
Then what I get is what I was expecting for
Tidak diragukan lagi: jika tes lulus, Anda dapat menegaskan bahwa Anda memberikan fitur yang berfungsi. Inilah yang dapat Anda sebut Nilai Bisnis .
Jika Anda ingin menulis tes unit untuk DoSomething
Anda harus berpura-pura (menggunakan beberapa ejekan) bahwa sisa kelas dan metode berfungsi (yaitu: bahwa, semua dependensi yang digunakan metode bekerja dengan benar) dan menegaskan metode Anda berfungsi.
Dalam praktiknya, Anda melakukan sesuatu seperti:
public SomeResults DoSomething(someInput) {
var someResult = [Do your job with someInput];
FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
return someResults;
}
Anda dapat melakukan ini dengan Injeksi Ketergantungan, atau beberapa Metode Pabrik atau Kerangka Kerja Mock atau memperluas kelas yang sedang diuji.
Misalkan ada bug di Log.DoSomething()
. Untungnya, spesifikasi Gherkin akan menemukannya dan tes end-to-end Anda akan gagal.
Fitur tidak akan berfungsi, karena Log
rusak, bukan karena [Do your job with someInput]
tidak melakukan tugasnya. Dan, omong-omong, [Do your job with someInput]
adalah satu-satunya tanggung jawab untuk metode itu.
Juga, anggaplah Log
digunakan dalam 100 fitur lain, dalam 100 metode lain dari 100 kelas lainnya.
Yap, 100 fitur akan gagal. Tetapi, untungnya, 100 tes end-to-end gagal juga dan mengungkapkan masalahnya. Dan, ya: mereka mengatakan yang sebenarnya .
Ini informasi yang sangat berguna: Saya tahu saya memiliki produk yang rusak. Ini juga informasi yang sangat membingungkan: tidak memberi tahu saya tentang di mana masalahnya. Ini mengomunikasikan saya gejala, bukan akar penyebabnya.
Namun, DoSomething
unit test berwarna hijau, karena menggunakan yang palsu Log
, dibuat untuk tidak pernah putus. Dan, ya: itu jelas berbohong . Ini mengkomunikasikan fitur yang rusak berfungsi. Bagaimana ini bisa bermanfaat?
(Jika DoSomething()
uji unit gagal, pastikan: [Do your job with someInput]
memiliki beberapa bug.)
Misalkan ini adalah sistem dengan kelas yang rusak:
Satu bug akan merusak beberapa fitur, dan beberapa tes integrasi akan gagal.
Di sisi lain, bug yang sama akan merusak hanya satu unit test.
Sekarang, bandingkan dua skenario.
Bug yang sama akan merusak hanya satu unit test.
- Semua fitur Anda menggunakan yang rusak
Log
berwarna merah
- Semua tes unit Anda berwarna hijau, hanya tes unit untuk
Log
yang merah
Sebenarnya, tes unit untuk semua modul menggunakan fitur yang rusak berwarna hijau karena, dengan menggunakan tiruan, mereka menghapus dependensi. Dengan kata lain, mereka berlari di dunia fiksi yang ideal. Dan ini adalah satu-satunya cara untuk mengisolasi bug dan mencari mereka. Pengujian unit berarti mengejek. Jika Anda tidak mengejek, Anda bukan pengujian unit.
Perbedaan
Tes integrasi memberi tahu apa yang tidak berfungsi. Tapi mereka tidak ada gunanya menebak di mana masalahnya.
Tes unit adalah satu-satunya tes yang memberi tahu Anda di mana tepatnya bug itu berada. Untuk menggambar informasi ini, mereka harus menjalankan metode di lingkungan yang diejek, di mana semua dependensi lainnya seharusnya berfungsi dengan benar.
Itu sebabnya saya berpikir bahwa kalimat Anda "Atau itu hanya tes unit yang mencakup 2 kelas" entah bagaimana dipindahkan. Tes unit tidak boleh menjangkau 2 kelas.
Jawaban ini pada dasarnya adalah ringkasan dari apa yang saya tulis di sini: Tes unit berbohong, itu sebabnya saya suka mereka .
Ketika saya menulis unit test saya membatasi ruang lingkup kode yang sedang diuji untuk kelas saya sedang menulis dengan mengejek dependensi. Jika saya menulis kelas Kalimat, dan Kalimat memiliki ketergantungan pada Word, saya akan menggunakan kata tiruan. Dengan mengejek Word, saya hanya dapat fokus pada antarmuka dan menguji berbagai perilaku kelas Kalimat saya saat berinteraksi dengan antarmuka Word. Dengan cara ini saya hanya menguji perilaku dan implementasi Kalimat dan tidak sekaligus menguji implementasi Word.
Setelah saya menulis unit test untuk memastikan Kalimat berperilaku benar ketika berinteraksi dengan Word berdasarkan antarmuka Word, maka saya menulis tes integrasi untuk memastikan bahwa asumsi saya tentang interaksi itu benar. Untuk ini saya menyediakan objek yang sebenarnya dan menulis tes yang menjalankan fitur yang akan berakhir menggunakan Kalimat dan Kata.
sumber
10 bit saya: D
Saya selalu diberitahu bahwa Tes Unit adalah pengujian komponen individu - yang harus dilakukan sepenuhnya. Sekarang, ini cenderung memiliki banyak tingkatan, karena sebagian besar komponen terbuat dari bagian yang lebih kecil. Bagi saya, sebuah unit adalah bagian fungsional dari sistem. Jadi itu harus memberikan sesuatu yang bernilai (yaitu bukan metode untuk parsing string, tapi mungkin HtmlSanitizer ).
Tes Integrasi adalah langkah berikutnya, mengambil satu atau lebih komponen dan memastikan mereka bekerja bersama sebagaimana mestinya .. Anda kemudian berada di atas seluk-beluk khawatir tentang bagaimana komponen bekerja secara individual, tetapi ketika Anda memasukkan html ke dalam HtmlEditControl Anda , itu entah bagaimana secara ajaib tahu apakah itu valid atau tidak ..
Ini adalah garis bergerak yang nyata .. Saya lebih suka lebih fokus pada mendapatkan kode sialan untuk bekerja penuh berhenti ^ _ ^
sumber
Tes unit menggunakan tiruan
Hal yang Anda bicarakan adalah tes integrasi yang sebenarnya menguji keseluruhan integrasi sistem Anda. Tetapi ketika Anda melakukan pengujian unit Anda harus benar-benar menguji setiap unit secara terpisah. Segala sesuatu yang lain harus diejek. Jadi dalam kasus
Sentence
kelas Anda, jika menggunakanWord
kelas, makaWord
kelas Anda harus diejek. Dengan cara ini, Anda hanya akan mengujiSentence
fungsionalitas kelas Anda .sumber
Saya pikir ketika Anda mulai berpikir tentang tes integrasi, Anda berbicara lebih banyak tentang persilangan antara lapisan fisik daripada lapisan logis.
Misalnya, jika pengujian Anda berkaitan dengan menghasilkan konten, itu adalah tes unit: jika tes Anda hanya menyangkut menulis ke disk, itu masih merupakan unit test, tetapi begitu Anda menguji I / O DAN konten file, maka Anda memiliki tes integrasi. Ketika Anda menguji output dari suatu fungsi dalam suatu layanan, ini adalah unit-test, tetapi begitu Anda membuat panggilan layanan dan melihat apakah hasil fungsi sama, maka itu adalah tes integrasi.
Secara teknis Anda tidak dapat menguji unit hanya satu kelas saja. Bagaimana jika kelas Anda terdiri dari beberapa kelas lain? Apakah itu secara otomatis membuatnya menjadi tes integrasi? Saya kira tidak.
sumber
menggunakan desain tanggung jawab tunggal, hitam dan putih. Lebih dari 1 tanggung jawab, ini merupakan tes integrasi.
Dengan tes bebek (terlihat, dukun, waddle, ini bebek), itu hanya tes unit dengan lebih dari 1 objek baru di dalamnya.
Ketika Anda masuk ke MVC dan mengujinya, tes kontroler selalu integrasi, karena controller berisi unit model dan unit tampilan. Menguji logika dalam model itu, saya akan memanggil unit test.
sumber
Sifat tes Anda
Sebuah tes unit modul X adalah tes yang mengharapkan (dan memeriksa) masalah hanya dalam X. modul
Tes integrasi banyak modul adalah tes yang mengharapkan masalah yang muncul dari kerja sama antara modul sehingga masalah ini akan sulit ditemukan menggunakan unit test saja.
Pikirkan sifat tes Anda dalam istilah berikut:
Ingatlah bahwa tes integrasi mungkin masih mematikan / memalsukan / menghilangkan beberapa dependensinya. Ini memberikan banyak jalan tengah antara tes unit dan tes sistem (tes integrasi paling komprehensif, menguji semua sistem).
Pendekatan pragmatis untuk menggunakan keduanya
Jadi pendekatan pragmatis adalah: Secara fleksibel bergantung pada tes integrasi sebanyak yang Anda bisa dan menggunakan tes unit di mana ini akan terlalu berisiko atau tidak nyaman. Cara berpikir ini mungkin lebih bermanfaat daripada beberapa diskriminasi dogmatis dari tes unit dan tes integrasi.
sumber
Dalam unit test Anda menguji setiap bagian yang terisolasi:
dalam pengujian integrasi Anda menguji banyak modul sistem Anda:
dan inilah yang terjadi ketika Anda hanya menggunakan unit test (umumnya kedua windows berfungsi, sayangnya tidak bersamaan):
Sumber: sumber1 sumber2
sumber
Menurut saya jawabannya adalah "Mengapa itu penting?"
Apakah karena tes unit adalah sesuatu yang Anda lakukan dan tes integrasi adalah sesuatu yang tidak Anda lakukan? Atau sebaliknya? Tentu saja tidak, Anda harus mencoba melakukan keduanya.
Apakah karena tes unit harus Cepat, Terisolasi, Diulang, Validasi Sendiri dan Tepat Waktu dan tes integrasi tidak boleh? Tentu saja tidak, semua tes harus ini.
Itu karena Anda menggunakan ejekan dalam tes unit tetapi Anda tidak menggunakannya dalam tes integrasi? Tentu saja tidak. Ini akan menyiratkan bahwa jika saya memiliki tes integrasi yang berguna saya tidak diizinkan untuk menambah tiruan untuk beberapa bagian, takut saya harus mengubah nama tes saya menjadi "unit test" atau menyerahkannya kepada programmer lain untuk dikerjakan.
Apakah karena tes unit menguji satu unit dan tes integrasi menguji sejumlah unit? Tentu saja tidak. Apa kepentingan praktisnya? Diskusi teoretis tentang ruang lingkup tes terurai dalam praktik karena istilah "unit" sepenuhnya bergantung pada konteks. Di tingkat kelas, sebuah unit mungkin menjadi metode. Pada tingkat perakitan, unit mungkin kelas, dan pada tingkat layanan, unit mungkin menjadi komponen. Dan bahkan kelas menggunakan kelas lain, jadi mana unitnya?
Itu tidak penting.
Pengujian itu penting, PERTAMA penting, membelah rambut tentang definisi adalah buang-buang waktu yang hanya membingungkan pendatang baru untuk pengujian.
sumber
Saya pikir saya masih akan memanggil beberapa kelas yang berinteraksi tes unit asalkan tes unit untuk class1 menguji fitur class1, dan tes unit untuk class2 menguji fitur-fiturnya, dan juga bahwa mereka tidak mengenai database.
Saya menyebut tes sebagai tes integrasi ketika dijalankan melalui sebagian besar tumpukan saya dan bahkan mengenai basis data.
Saya sangat menyukai pertanyaan ini, karena diskusi TDD terkadang terasa terlalu murni bagi saya, dan baik bagi saya untuk melihat beberapa contoh nyata.
sumber
Saya melakukan hal yang sama - Saya menyebut mereka semua unit test, tetapi pada titik tertentu saya memiliki "unit test" yang mencakup begitu banyak sehingga saya sering mengganti nama menjadi "..IntegrationTest" - hanya perubahan nama saja, tidak ada perubahan lain.
Saya pikir ada kelanjutan dari "tes atom" (pengujian satu kelas kecil, atau metode) ke tes unit (tingkat kelas) dan tes integrasi - dan kemudian tes fungsional (yang biasanya mencakup lebih banyak barang dari atas ke bawah) - Sepertinya tidak ada potongan bersih.
Jika tes Anda mengatur data, dan mungkin memuat database / file dll, maka mungkin lebih dari tes integrasi (tes integrasi saya menemukan menggunakan lebih sedikit mengejek dan kelas yang lebih nyata, tetapi itu tidak berarti Anda tidak dapat mengejek beberapa dari sistem).
sumber
Unit Testing adalah metode pengujian yang memverifikasi masing-masing unit kode sumber berfungsi dengan baik.
Pengujian Integrasi adalah fase pengujian perangkat lunak di mana modul perangkat lunak individu digabungkan dan diuji sebagai suatu kelompok.
Wikipedia mendefinisikan sebuah unit sebagai bagian terkecil yang dapat diuji dari suatu aplikasi, yang dalam Java / C # adalah sebuah metode. Tetapi dalam contoh Anda kelas Word dan Kalimat saya mungkin hanya akan menulis tes untuk kalimat karena saya mungkin akan menemukan itu berlebihan untuk menggunakan kelas kata tiruan untuk menguji kelas kalimat. Jadi kalimat akan menjadi unit saya dan kata adalah detail implementasi dari unit itu.
sumber
Tes integrasi: Kegigihan basis data diuji.
Tes unit: Akses basis data diejek. Metode kode diuji.
sumber
Pengujian unit adalah pengujian terhadap unit kerja atau blok kode jika Anda suka. Biasanya dilakukan oleh pengembang tunggal.
Pengujian integrasi mengacu pada tes yang dilakukan, lebih disukai pada server integrasi, ketika pengembang melakukan kode mereka ke repositori kontrol sumber. Pengujian integrasi mungkin dilakukan oleh utilitas seperti Cruise Control.
Jadi Anda melakukan pengujian unit Anda untuk memvalidasi bahwa unit kerja yang Anda buat berfungsi dan kemudian tes integrasi memvalidasi bahwa apa pun yang Anda tambahkan ke repositori tidak merusak sesuatu yang lain.
sumber
Saya sebut unit menguji tes-tes yang kotak putih menguji kelas. Setiap dependensi yang diperlukan kelas diganti dengan yang palsu (mengejek).
Tes integrasi adalah tes di mana beberapa kelas dan interaksinya diuji pada saat yang sama. Hanya beberapa dependensi dalam kasus ini yang dipalsukan / diejek.
Saya tidak akan menyebut tes integrasi Pengontrol kecuali salah satu dari dependensi mereka adalah nyata (yaitu tidak dipalsukan) (mis. IFormsAuthentication).
Memisahkan kedua jenis tes berguna untuk menguji sistem pada level yang berbeda. Juga, tes integrasi cenderung berumur panjang, dan tes unit seharusnya cepat. Perbedaan kecepatan eksekusi berarti mereka dieksekusi secara berbeda. Dalam proses dev kami, tes unit dijalankan pada saat check-in (yang bagus karena sangat cepat), dan tes integrasi dijalankan sekali / dua kali per hari. Saya mencoba dan menjalankan tes integrasi sesering mungkin, tetapi biasanya mengenai database / menulis ke file / membuat rpc's / etc melambat.
Itu memunculkan poin penting lainnya, unit test harus menghindari memukul IO (misalnya disk, jaringan, db). Kalau tidak, mereka memperlambat banyak. Dibutuhkan sedikit usaha untuk mendesain dependensi IO ini - saya tidak bisa mengakui bahwa saya setia pada aturan "unit test harus cepat", tetapi jika ya, manfaat pada sistem yang jauh lebih besar menjadi nyata dengan sangat cepat .
sumber
Penjelasan Sederhana dengan Analogi
Contoh di atas sangat baik dan saya tidak perlu mengulanginya. Jadi saya akan fokus menggunakan contoh untuk membantu Anda memahami.
Tes Integrasi
Tes integrasi memeriksa apakah semuanya bekerja bersama. Bayangkan serangkaian roda gigi yang bekerja bersama dalam sebuah arloji. Tes integrasi adalah: apakah arloji memberitahukan waktu yang tepat? Apakah masih mengatakan waktu yang tepat dalam 3 hari?
Semua itu memberi tahu Anda apakah keseluruhan bagian itu berfungsi. Jika gagal: itu tidak memberi tahu Anda persis di mana ia gagal.
Tes Unit
Ini adalah jenis tes yang sangat spesifik. Mereka memberi tahu Anda apakah satu hal spesifik berfungsi atau gagal. Kunci dari jenis tes ini adalah bahwa ia hanya menguji satu hal tertentu sambil mengasumsikan bahwa semua yang lain berfungsi dengan baik. Itulah poin kuncinya.
Contoh: Mari kita uraikan hal ini menggunakan contoh:
Menggunakan Rintisan bertopik
Misalkan tes integrasi mobil Anda gagal. Itu tidak berhasil mengemudi ke Echuca. Dimana masalahnya?
Sekarang mari kita anggap mesin Anda menggunakan sistem injeksi bahan bakar khusus dan pengujian unit mesin ini juga gagal. Dengan kata lain, baik uji integrasi dan uji unit mesin gagal. Lalu di mana masalahnya? (Beri diri Anda 10 detik untuk mendapatkan jawabannya.)
Apakah masalah dengan mesin, atau dengan sistem injeksi bahan bakar?
Anda melihat masalahnya di sini? Anda tidak tahu apa yang sebenarnya gagal. Jika Anda menggunakan dependensi eksternal yang berbeda, maka masing-masing dari 10 itu dapat menyebabkan masalah - dan Anda tidak akan tahu harus mulai dari mana. Itu sebabnya unit test menggunakan bertopik untuk menganggap bahwa semua yang lain berfungsi dengan baik.
sumber
Sedikit akademik pertanyaan ini, bukan? ;-) Pandangan saya: Bagi saya tes integrasi adalah tes seluruh bagian, bukan jika dua bagian dari sepuluh berjalan bersama. Tes integrasi kami menunjukkan, jika bangunan induk (berisi 40 proyek) akan berhasil. Untuk proyek kami memiliki banyak unit test. Yang paling penting mengenai tes unit bagi saya adalah, bahwa satu tes unit tidak harus tergantung pada tes unit lain. Jadi bagi saya kedua tes yang Anda jelaskan di atas adalah unit test, jika mereka independen. Untuk tes integrasi ini tidak perlu menjadi penting.
sumber
Saya pikir Ya dan Ya. Tes unit Anda yang mencakup 2 kelas menjadi tes integrasi.
Anda bisa menghindarinya dengan menguji kelas Kalimat dengan implementasi mock - kelas MockWord, yang penting ketika bagian-bagian sistem cukup besar untuk diimplementasikan oleh pengembang yang berbeda. Dalam hal itu Word adalah unit yang diuji sendiri, Sentence adalah unit yang diuji dengan bantuan MockWord, dan kemudian Kalimat diuji integrasi dengan Word.
Contoh perbedaan nyata dapat mengikuti 1) Array 1.000.000 elemen mudah diuji unit dan berfungsi dengan baik. 2) BubbleSort mudah diuji unit pada array tiruan dari 10 elemen dan juga berfungsi dengan baik 3) Pengujian integrasi menunjukkan bahwa ada sesuatu yang tidak begitu baik.
Jika bagian-bagian ini dikembangkan oleh satu orang, kemungkinan besar masalah akan ditemukan saat unit menguji BubbleSoft hanya karena pengembang sudah memiliki array nyata dan dia tidak perlu implementasi tiruan.
sumber
Selain itu, penting untuk diingat bahwa tes unit dan tes integrasi dapat diotomatisasi dan ditulis menggunakan, misalnya, JUnit. Dalam tes integrasi JUnit, seseorang dapat menggunakan
org.junit.Assume
kelas untuk menguji ketersediaan elemen lingkungan (misalnya, koneksi database) atau kondisi lainnya.sumber
Jika Anda seorang purist TDD, Anda menulis tes sebelum Anda menulis kode produksi. Tentu saja, tes tidak akan dikompilasi, jadi pertama-tama Anda membuat tes dikompilasi, lalu lulus tes.
Anda dapat melakukan ini dengan tes unit, tetapi Anda tidak bisa dengan tes integrasi atau penerimaan. Jika Anda mencoba dengan tes integrasi, tidak ada yang akan dikompilasi sampai Anda selesai!
sumber