Apa perbedaan antara tes integrasi dan unit?

307

Saya tahu apa yang disebut definisi buku teks tentang tes unit dan tes integrasi. Yang saya ingin tahu adalah ketika saatnya untuk menulis tes unit ... Saya akan menulisnya untuk mencakup sebanyak mungkin set kelas.

Sebagai contoh, jika saya memiliki Wordkelas, saya akan menulis beberapa tes unit untuk Wordkelas tersebut. Kemudian, saya mulai menulis Sentencekelas saya , dan ketika perlu berinteraksi dengan Wordkelas, saya akan sering menulis tes unit saya sehingga mereka menguji keduanya Sentencedan Word... setidaknya di tempat mereka berinteraksi.

Apakah tes ini pada dasarnya menjadi tes integrasi karena mereka sekarang menguji integrasi 2 kelas ini, atau hanya tes unit yang mencakup 2 kelas?

Secara umum, karena garis yang tidak pasti ini, saya jarang akan benar-benar menulis tes integrasi ... atau saya menggunakan produk jadi untuk melihat apakah semua bagian bekerja dengan baik tes integrasi yang sebenarnya, meskipun mereka manual dan jarang diulangi di luar ruang lingkup dari setiap fitur individu?

Apakah saya salah memahami tes integrasi, atau apakah benar-benar ada sedikit perbedaan antara tes integrasi dan unit?

Mike Stone
sumber

Jawaban:

300

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

DoSomethingsangat 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 DoSomethingAnda 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 Logrusak, 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 Logdigunakan 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, DoSomethingunit 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: Sistem dengan kelas yang rusak

Satu bug akan merusak beberapa fitur, dan beberapa tes integrasi akan gagal.

Satu bug akan merusak beberapa fitur, dan beberapa tes integrasi akan gagal

Di sisi lain, bug yang sama akan merusak hanya satu unit test.

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 Logberwarna merah
  • Semua tes unit Anda berwarna hijau, hanya tes unit untuk Logyang 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 .

Arialdo Martini
sumber
6
Jawaban yang sangat bagus! Namun saya hanya ingin menambahkan bahwa mengejek bukan untuk unit test saja. Itu juga bisa sangat berguna dalam banyak kasus uji integrasi.
n.Stenvang
1
Jawaban bagus! Saya hanya tidak setuju dengan dua poin: 1) bahwa tes integrasi "tidak ada gunanya menebak di mana masalahnya"; dan 2) bahwa "tes unit tidak boleh menjangkau 2 kelas". Saya membuat banyak tes integrasi, dan ketika mereka rusak biasanya tidak sulit untuk menentukan sumber masalah, asalkan Anda mendapatkan jejak tumpukan penuh, atau pernyataan gagal tunggal (dalam hal ini mungkin lebih sulit untuk menemukan sumbernya, tetapi tidak begitu banyak, karena tes integrasi menyediakan konteks yang terkandung untuk debugging). (lanjutan)
Rogério
5
Tes unit dapat menggunakan beberapa kelas, asalkan itu bukan kelas publik yang seharusnya memiliki tes unit tersendiri. Satu kasus adalah ketika kelas yang diuji publik menggunakan kelas pembantu non-publik lainnya yang hanya ada untuk mendukung kelas publik; dalam hal ini, "unit" terdiri dari dua kelas atau lebih. Kasus lain adalah bahwa sebagian besar kelas menggunakan kelas pihak ketiga (kelas String / string, kelas koleksi, dll) yang tidak masuk akal untuk diejek atau diisolasi dari; kami hanya menganggap mereka sebagai dependensi yang stabil dan andal yang berada di luar cakupan pengujian.
Rogério
2
Dengan tes integrasi agak sulit untuk menemukan masalah root, tetapi Anda masih bisa men-debug dan menemukan masalah root. Dengan asumsi unit test tidak sering gagal, maka mungkin jarang dibutuhkan waktu lebih lama untuk memperbaiki bug jika Anda hanya memiliki tes integrasi, tetapi kemudian Anda mendapatkan nilai tambah dari pengujian integrasi komponen juga dan Anda menghemat waktu menulis tes unit. Saya pikir klaim ini (yang datang dari bos saya) salah, tapi saya tidak yakin bagaimana saya bisa meyakinkannya, ada ide?
BornToCode
1
Dengan alasan dalam jawaban ini, orang dapat berargumentasi bahwa mungkin lebih efektif untuk melewatkan tes unit tulis dan menghabiskan waktu yang dihemat dengan mencari sumber kegagalan tes integrasi ketika gagal.
62

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.

Larry Foulkrod
sumber
43

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

Rob Cooper
sumber
23

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 Sentencekelas Anda, jika menggunakan Wordkelas, maka Wordkelas Anda harus diejek. Dengan cara ini, Anda hanya akan menguji Sentencefungsionalitas kelas Anda .

Robert Koritnik
sumber
Saya tahu ini adalah posting lama tapi saya baru saja menemukannya. Bagaimana jika Anda memiliki kelas ketiga bernama Font yang berinteraksi dengan kelas Kalimat dan Anda ingin menguji fungsionalitas antara kelas Word dan Kalimat, maka Anda harus mengejek kelas Font tetapi ini tidak akan membuatnya menjadi unit test. Jadi yang saya katakan adalah bahwa menggunakan tiruan tidak selalu membuatnya menjadi unit test, tiruan juga dapat digunakan dalam tes integrasi.
n.Stenvang
2
Tentu saja mengolok-olok dapat digunakan dalam tes integrasi, tetapi agar tes unit untuk benar-benar menjadi seperti segala sesuatu eksternal ke unit yang harus disimulasikan . Jika tes integrasi menggunakan tiruan, maka itu kemungkinan tes integrasi parsial (jika istilah tersebut ada). Tentu saja ada tes integrasi parsial yang bersifat top-down atau bottom-up. Belakangan ini biasanya tidak membutuhkan ejekan sementara mantan melakukan.
Robert Koritnik
17

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.

Jon Limjap
sumber
8
"Secara teknis kamu tidak bisa menguji unit hanya satu kelas. Bagaimana jika kelasmu terdiri dari beberapa kelas lain?" Nah, tes unit "ketat" hanya akan mengejek / mematikan semua dependensi. Namun, masih bisa diperdebatkan apakah ini selalu praktis ...
sleske
2
Itu benar sieske - yang penting adalah untuk dapat menjaga dependensi seminimal mungkin.
Jon Limjap
-1, tes unit tidak menguji fitur tunggal, tetapi fungsi perangkat lunak tunggal atau kelas, yaitu tes unit logis perangkat lunak.
CharlesB
12

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.

MengembangkanChris
sumber
10

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:

  • Pengurangan risiko : Itulah gunanya tes. Hanya kombinasi tes unit dan tes integrasi yang dapat memberikan Anda pengurangan risiko penuh, karena di satu sisi tes unit dapat secara inheren tidak menguji interaksi yang tepat antara modul dan di sisi lain tes integrasi dapat menjalankan fungsi modul non-sepele saja. sedikit banyak.
  • Upaya menulis tes: Tes integrasi dapat menghemat usaha karena Anda mungkin tidak perlu menulis tulisan rintisan / palsu / mengejek. Tetapi unit test dapat menghemat usaha juga, ketika menerapkan (dan memelihara!) Bertopik / palsu / mengolok-olok itu ternyata lebih mudah daripada mengkonfigurasi pengaturan pengujian tanpa mereka.
  • Keterlambatan pelaksanaan tes: Tes integrasi yang melibatkan operasi kelas berat (seperti akses ke sistem eksternal seperti DB atau server jauh) cenderung lambat (er). Ini berarti unit test dapat dieksekusi jauh lebih sering, yang mengurangi upaya debug jika ada yang gagal, karena Anda memiliki ide yang lebih baik tentang apa yang telah Anda ubah sementara itu. Ini menjadi sangat penting jika Anda menggunakan test-driven development (TDD).
  • Upaya debugging : Jika tes integrasi gagal, tetapi tidak ada tes unit yang melakukannya, ini bisa sangat merepotkan, karena ada begitu banyak kode yang terlibat yang mungkin mengandung masalah. Ini bukan masalah besar jika sebelumnya Anda hanya mengubah beberapa baris - tetapi karena tes integrasi berjalan lambat, Anda mungkin tidak menjalankannya dalam interval sesingkat itu ...

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.

Lutz Prechelt
sumber
10

Dalam unit test Anda menguji setiap bagian yang terisolasi: masukkan deskripsi gambar di sini

dalam pengujian integrasi Anda menguji banyak modul sistem Anda:

masukkan deskripsi gambar di sini

dan inilah yang terjadi ketika Anda hanya menggunakan unit test (umumnya kedua windows berfungsi, sayangnya tidak bersamaan):

masukkan deskripsi gambar di sini

Sumber: sumber1 sumber2

Michu93
sumber
Anda memiliki tiga gambar tetapi hanya dua sumber.
gerrit
1
@gerit lihat sumber pertama - dua gambar dari sana
Michu93
1
Suka jawaban ini 👏
Dzenis H.
8

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.

David Sackstein
sumber
5
-1 Definisi adalah apa yang membuat orang dapat menggunakan istilah yang sama tanpa selalu menjelaskan apa artinya, dan sangat penting untuk kolaborasi. Karena itu, penting untuk memahami perbedaan antara kedua konsep tersebut.
CharlesB
Seperti @CharlesB sebutkan itu penting sehingga tidak perlu menjelaskan setiap kali atau menemukan setiap orang memiliki definisi yang berbeda yang menyebabkan kebingungan. Tes akan ditulis berbeda dan dijalankan secara berbeda, tetapi ini tidak menyarankan keduanya tidak boleh dilakukan dengan ingin mendefinisikan perbedaan.
Shane
Kesimpulan jawaban mungkin ekstrim, tetapi sebagian besar poin yang cukup valid: Unit test dan tes integrasi yang sebagian besar hal yang sama kecuali untuk rincian mereka - dan itu tidak jelas di mana garis harus ditarik antara mereka.
Lutz Prechelt
Ini tidak membantu saat membuat bahasa umum di lingkungan profesional. Meskipun sebagian besar, Anda benar, tidak masalah banyak, tidak memiliki bahasa yang sama akan menciptakan kesalahpahaman dan kebingungan di antara tim. Saya pikir pilihan terbaik adalah membuat tim menyetujui syarat dan definisi mereka.
user924272
4

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.

Lance Fisher
sumber
4

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

Michael Neale
sumber
4

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.

grom
sumber
4

Tes integrasi: Kegigihan basis data diuji.
Tes unit: Akses basis data diejek. Metode kode diuji.

Pascal
sumber
3

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.

Christian Hagelid
sumber
2

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 .

CVertex
sumber
2

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:

  • Mari kita ambil mobil sebagai contoh.
  • Tes integrasi untuk mobil: mis. Apakah mobil itu mengendarai mobil ke Woop Woop dan kembali? Jika berhasil, Anda dapat dengan aman mengatakan bahwa mobil bekerja dari sudut pandang keseluruhan. Ini adalah tes integrasi. Jika gagal Anda tidak tahu di mana itu sebenarnya gagal: apakah radiator, transmisi, mesin, atau karburator? Anda tidak tahu. Itu bisa apa saja.
  • Tes unit untuk mobil: Apakah mesinnya bekerja? Tes ini mengasumsikan bahwa semua yang ada di mobil bekerja dengan baik. Dengan begitu, jika pengujian unit khusus ini gagal: Anda bisa sangat yakin bahwa masalahnya ada pada mesin - sehingga Anda dapat dengan cepat mengisolasi dan memperbaiki masalah.

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.

BKSpurgeon
sumber
1

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.

John Smithers
sumber
1

Apakah tes ini pada dasarnya menjadi tes integrasi karena mereka sekarang menguji integrasi 2 kelas ini? Atau itu hanya tes unit yang mencakup 2 kelas?

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.

Pavel Feldman
sumber
1

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.Assumekelas untuk menguji ketersediaan elemen lingkungan (misalnya, koneksi database) atau kondisi lainnya.

Paulo Merson
sumber
0

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!

StevePoling
sumber