Apakah saya memerlukan tes unit jika saya sudah memiliki tes integrasi?

47

Jika saya sudah memiliki tes integrasi untuk program saya, dan mereka semua lulus, maka saya merasa itu akan berhasil. Lalu apa alasan untuk menulis / menambah unit test? Karena saya sudah harus menulis tes integrasi, saya hanya ingin menulis unit test untuk bagian yang tidak tercakup oleh tes integrasi.

Apa yang saya tahu manfaat dari tes unit daripada tes integrasi

  • Kecil dan karenanya cepat dijalankan (tetapi menambahkan unit baru untuk menguji sesuatu sudah diuji dengan uji integrasi berarti total test suit saya menjadi lebih besar dan lebih lama untuk dijalankan)
  • Temukan bug lebih mudah karena hanya menguji satu hal (tapi saya bisa mulai menulis unit test untuk memverifikasi setiap bagian individu ketika tes integrasi saya gagal)
  • Temukan bug yang mungkin tidak tertangkap dalam tes integrasi. mis. bug masking / offsetting. (tetapi jika integrasi saya menguji semua yang lulus, yang berarti program saya akan bekerja bahkan ada bug tersembunyi ada. Jadi temukan / perbaiki bug ini bukan prioritas yang sangat tinggi kecuali mereka mulai melanggar tes integrasi di masa depan atau menyebabkan masalah kinerja)

Dan kami selalu ingin menulis lebih sedikit kode, tetapi tes unit tulis membutuhkan lebih banyak kode (terutama mengatur objek tiruan). Perbedaan antara beberapa tes unit saya dan tes integrasi adalah bahwa dalam tes unit, saya menggunakan objek tiruan, dan dalam tes integrasi, saya menggunakan objek nyata. Yang memiliki banyak duplikasi dan saya tidak suka kode duplikat, bahkan dalam tes karena ini menambah overhead untuk mengubah perilaku kode (alat refactor tidak dapat melakukan semua pekerjaan sepanjang waktu).

Bryan Chen
sumber
Hanya ingin tahu, berapa banyak cakupan tes integrasi Anda miliki? Juga, jika Anda memiliki logika yang kompleks, apakah tes integrasi Anda mencakup semuanya atau hanya sebagian saja dan bagian mana, penting untuk bisnis atau acak?
Civan
Pertanyaan ini sepertinya tidak jelas. Katakanlah saya memiliki metode pengendali Rails yang memanggil interaksor ( github.com/collectiveidea/interactor ). Saya telah memutuskan untuk menulis tes integrasi untuk metode pengontrol saya (karena tanpa itu saya tidak dapat mempercayai bahwa titik akhir API saya berfungsi). Setidaknya ada dua pertanyaan di sini: (1) haruskah saya juga menulis tes unit untuk metode pengontrol saya (yaitu, haruskah saya menulis tes unit yang menguji perilaku yang sama dengan tes integrasi saya), dan (2) haruskah saya juga menulis tes unit untuk interaksiku? Saya akan menjawab dua pertanyaan ini secara berbeda dalam konteks bisnis tertentu.
Daniel

Jawaban:

33

Anda telah memberikan argumen yang bagus untuk dan menentang pengujian unit. Jadi, Anda harus bertanya pada diri sendiri, " Apakah saya melihat nilai dalam argumen positif yang lebih besar daripada biaya dalam yang negatif? " Tentu saja saya:

  • Kecil-dan-cepat adalah aspek pengujian unit yang bagus, meskipun bukan yang paling penting.
  • Menemukan bug lebih mudah sangat berharga. Banyak penelitian tentang pengembangan perangkat lunak profesional telah menunjukkan bahwa biaya bug meningkat tajam seiring bertambahnya usia dan bergerak menuruni jalur pengiriman perangkat lunak.
  • Menemukan bug-masked sangat berharga. Ketika Anda tahu bahwa komponen tertentu memiliki semua perilakunya diverifikasi, Anda dapat menggunakannya dengan cara yang sebelumnya tidak digunakan, dengan keyakinan. Jika satu-satunya verifikasi adalah melalui pengujian integrasi, Anda hanya tahu bahwa penggunaannya saat ini berlaku dengan benar.
  • Mengejek itu mahal dalam kasus dunia nyata, dan memelihara ejekan adalah dua kali lipat. Bahkan, ketika mengejek objek atau antarmuka "menarik", Anda bahkan mungkin perlu tes yang memverifikasi bahwa objek tiruan Anda memodelkan objek nyata dengan benar!

Dalam buku saya, pro lebih besar daripada kontra.

Ross Patterson
sumber
2
Bukankah mengejek lebih murah dalam kasus dunia nyata? Anda hanya mengatur harapan dari pesan apa yang diterima mock dan menentukan apa yang akan dikembalikan.
Dogweather
10
@Dogweather Mocks berfungsi dengan baik saat pertama kali dibuat. Dengan berlalunya waktu dan objek yang sebenarnya diubah, tiruan harus berubah dengannya. 10 tahun dan 6.000 unit tes di jalan, sangat sulit untuk mengetahui bahwa tes "sukses" Anda benar-benar berhasil.
Ross Patterson
1
Selain itu, "10 tahun dan 6.000 unit tes" adalah angka dari pengalaman pribadi, bukan hiperbola.
Ross Patterson
3
Saya mulai menulis tes pengembang otomatis (unit dan integrasi, tetapi sebagian besar yang terakhir) pada tahun 2004 atau 2005, dan mengembangkan perpustakaan mengejek canggih untuk Jawa. Banyak kali saya melihat beberapa tes integrasi melanggar untuk alasan yang sama (seperti perubahan dalam DB, atau perubahan jaringan), dan saya kadang-kadang menulis tes integrasi "tingkat rendah" untuk komponen yang dapat digunakan kembali, tetapi tetap saja, saya lebih suka hanya memiliki tes integrasi. Tes unit terisolasi dengan mengejek, sebagian besar waktu, tidak layak; Saya menerapkan ejekan hanya sebagai bantuan untuk tes integrasi.
Rogério
Poin terakhir Anda tampaknya bertentangan dengan argumen yang Anda buat. Dalam poin ini Anda membuat kasus terhadap penulisan ejekan yang tidak perlu, yang merupakan argumen terhadap penulisan unit test untuk bagian yang sudah dicakup oleh tes integrasi. Dorongan argumen Anda, bagaimanapun, mendukung penulisan unit test untuk bagian-bagian yang sudah dicakup oleh tes integrasi. Bisakah Anda menjelaskan maksud Anda di sini @RossPatterson?
Daniel
8

Saya tidak melihat banyak nilai dalam mengimplementasikan kembali testcase integrasi yang ada sebagai yang paling tidak kompatibel.

Tes integrasi seringkali jauh lebih mudah untuk ditulis untuk aplikasi warisan non tdd karena biasanya fungsionalitas yang akan diuji secara ketat digabungkan sehingga unit pengujian dalam isolasi (= unittesting) dapat menjadi sulit / mahal / tidak mungkin.

> Then what are the reasons to write/add unit tests?

Menurut pendapat saya pengembangan yang digerakkan oleh tes paling efektif jika Anda menulis unit test sebelum kode aktual. Dengan cara ini kode yang memenuhi tes menjadi jelas dipisahkan dengan referensi eksternal minimum yang mudah diuji.

Jika kode sudah ada tanpa tes unit, biasanya banyak pekerjaan tambahan untuk menulis tes unit setelah itu karena kode itu tidak ditulis untuk pengujian mudah.

Jika Anda melakukan TDD kode secara otomatis mudah diuji.

k3b
sumber
2
Jika saya memiliki aplikasi warisan tanpa unit-tests, dan saya ingin memasukkan unit-testsuntuk bagian-bagian tertentu, menurut Anda lebih baik menulis dulu integration testsuntuk kode warisan. Setelah itu ditulis, maka Anda dapat melepaskan kopling ketat, dan membuat fungsi dengan antarmuka yang dapat diuji? Karena Anda integration-testsudah menulis, Anda dapat memverifikasi pada setiap langkah refactoring, bahwa versi baru kode masih berfungsi seperti yang diinginkan?
alpha_989
2
@ alpha_989, ini sangat IMHO dan saya terbuka untuk mendengar ide-ide lain, tapi saya lebih suka Tes Integrasi daripada Tes Unit untuk Kode Warisan. Dalam kedua kasus tersebut, Anda harus yakin bahwa metode tersebut bekerja dengan benar sebelum menambahkan jenis pengujian apa pun, tetapi Pengujian Integrasi memastikan bahwa keseluruhan harapan metode tersebut bekerja berlawanan dengan elemen kode individual.
Britt Wescott
5

Tes integrasi seharusnya hanya memverifikasi bahwa beberapa komponen bekerja bersama seperti yang diharapkan. Apakah logika masing-masing komponen akurat atau tidak harus diverifikasi oleh unit test.
Sebagian besar metode memiliki beberapa jalur eksekusi yang memungkinkan; pikirkan if-then-else's, variabel input dengan nilai yang salah tak terduga atau sekadar salah, dll. Biasanya pengembang cenderung hanya memikirkan jalur bahagia: jalur normal yang tidak salah. Tetapi sejauh menyangkut jalur lain itu, Anda memiliki dua opsi: Anda dapat membiarkan pengguna akhir menjelajahi jalur itu melalui tindakan yang diambil di UI dan berharap mereka tidak membuat crash aplikasi Anda, atau Anda dapat menulis unit test yang menegaskan perilaku dari jalan-jalan lain itu dan mengambil tindakan bila perlu.

Stefan Billiet
sumber
4

Beberapa alasan yang Anda tunjukkan dalam pertanyaan Anda benar-benar penting dan dengan sendirinya bisa membuat kasus yang mendukung pengujian unit, tetapi YMMV. Misalnya, seberapa sering Anda menjalankan test suite terintegrasi Anda? Pengalaman saya dengan tes terintegrasi adalah cepat atau lambat mereka akan menjadi sangat lambat Anda tidak akan menjalankannya setiap kali Anda membuat perubahan dan waktu antara memasukkan dan mendeteksi bug akan meningkat.

Juga, kesalahan besar yang mungkin Anda lakukan adalah mempercayainya

Find bug that may not be caught in integration test. e.g. masking/offsetting bugs.

tidak penting. Apakah Anda mengharapkan pengguna menemukan bug untuk Anda? Memercayai pertanggungan yang diperoleh dari tes terintegrasi berbahaya menurut saya, Anda dapat dengan mudah mendapatkan% cakupan yang tinggi tetapi pada kenyataannya Anda menguji sangat sedikit.

Saya kira referensi kanonik terhadap tes terintegrasi adalah posting JBrains:

http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1

jika Anda belum membacanya.

Akhirnya, IMO umpan balik yang bisa Anda dapatkan dari unit test untuk desain Anda sangat berharga. Menilai desain dengan perasaan dan mengandalkan tes terintegrasi juga bisa menjadi kesalahan.

José Ricardo
sumber
Saya tidak begitu mendapatkan artikel itu. Jadi ada banyak jalur kode dan tes integrasi tidak dapat mencakup semuanya ... jadi? Hal yang sama berlaku untuk unit test kecuali unit Anda sangat sepele sehingga tidak ada gunanya.
Casey
Itu lebih seperti sebuah argumen yang menentang penetapan cakupan kode sama sekali daripada yang Anda harus menulis satu ton tes unit dan menghindari tes integrasi.
Casey
1

Jika Anda berharap harus memodifikasi atau memperbaiki kode Anda, memiliki unit test sangat penting. Tes unit ada tidak hanya untuk menunjukkan bug pada saat kode ditulis, tetapi untuk menunjukkan kapan bug baru muncul ketika lebih banyak kode ditulis.

Ya, jauh lebih baik untuk menulis integrasi dan tes unit Anda terlebih dahulu, tetapi ada banyak nilai untuk memilikinya bahkan jika mereka ditulis nanti.

Matthew Flynn
sumber
3
Saya tidak merasa Anda yang membuat kasus ini. Tes integrasi juga akan mengungkapkan bug dalam kode, dan pada kenyataannya mampu menangkap bug yang tidak akan diuji oleh unit.
Casey