Berapa banyak mengejek "tepat?"

10

Saya menamai pertanyaan itu dengan bercanda karena saya yakin "itu tergantung," tetapi saya punya beberapa pertanyaan spesifik.

Bekerja dalam perangkat lunak yang memiliki banyak lapisan ketergantungan, tim saya telah terbiasa menggunakan ejekan secara luas untuk memisahkan setiap modul kode dari dependensi di bawahnya.

Karena itu saya terkejut bahwa Roy Osherove menyarankan dalam video ini bahwa Anda harus menggunakan mengejek hanya sekitar 5% dari waktu. Saya kira kita duduk di suatu tempat antara 70-90%. Saya telah melihat panduan serupa lainnya dari waktu ke waktu juga.

Saya harus mendefinisikan apa yang saya anggap sebagai dua kategori "tes integrasi" yang sangat berbeda sehingga mereka benar-benar harus diberi nama yang berbeda: 1) Tes dalam proses yang mengintegrasikan beberapa modul kode dan 2) Tes luar proses yang berbicara ke basis data, sistem file, layanan web, dll. Ini adalah tipe # 1 yang saya khawatirkan, tes yang mengintegrasikan beberapa modul kode semua dalam proses.

Banyak dari panduan komunitas yang telah saya baca menunjukkan bahwa Anda harus lebih memilih sejumlah besar unit test terisolasi, berbutir halus dan sejumlah kecil tes integrasi end-to-end berbutir kasar, karena unit test memberi Anda umpan balik yang tepat di mana tepatnya regresi mungkin telah dibuat, tetapi pengujian kasar, yang rumit untuk diatur, sebenarnya memverifikasi lebih banyak fungsi ujung ke ujung sistem.

Mengingat hal ini, tampaknya perlu menggunakan ejekan yang agak sering untuk mengisolasi unit kode yang terpisah ini.

Diberikan model objek sebagai berikut:

masukkan deskripsi gambar di sini

... Juga pertimbangkan bahwa kedalaman ketergantungan aplikasi kita jauh lebih dalam daripada yang bisa saya muat dalam gambar ini, sehingga ada beberapa lapisan N antara lapisan 2-4 dan lapisan 5-13.

Jika saya ingin menguji beberapa keputusan logis sederhana yang dibuat di unit # 1, dan jika setiap ketergantungan adalah konstruktor-disuntikkan ke dalam modul kode yang tergantung padanya sehingga, katakanlah, 2, 3, dan 4 adalah konstruktor yang dimasukkan ke dalam modul 1 di gambar, saya lebih suka menyuntikkan mengejek 2, 3, dan 4 menjadi 1.

Kalau tidak, saya perlu membuat contoh konkret dari 2, 3, dan 4. Ini bisa lebih sulit daripada hanya mengetik tambahan. Seringkali 2, 3, dan 4 akan memiliki persyaratan konstruktor yang dapat menantang untuk memuaskan dan sesuai dengan grafik (dan sesuai dengan realitas proyek kami), saya perlu membuat contoh konkrit dari N hingga 13 untuk memuaskan konstruktor dari 2, 3, dan 4.

Situasi ini menjadi lebih menantang ketika saya membutuhkan 2, 3, atau 4 untuk berperilaku tertentu sehingga saya dapat menguji keputusan logis sederhana di # 1. Saya mungkin perlu memahami dan "secara mental beralasan tentang" seluruh objek grafik / pohon sekaligus untuk mendapatkan 2, 3, atau 4 untuk berperilaku dengan cara yang diperlukan. Seringkali tampak jauh lebih mudah untuk melakukan myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Returns (new Right ()); untuk menguji modul 1 itu merespon seperti yang diharapkan ketika modul 2 memberitahu itu untuk langsung ke kanan.

Jika saya menguji contoh konkret dari 2 ... N ... 13 bersama-sama, pengaturan uji akan sangat besar dan sebagian besar diduplikasi. Kegagalan pengujian mungkin tidak melakukan pekerjaan yang sangat baik untuk menentukan dengan tepat lokasi kegagalan regresi. Tes tidak akan independen ( tautan pendukung lain ).

Memang, seringkali masuk akal untuk melakukan pengujian lapisan bawah berbasis negara, daripada berbasis interaksi, karena modul-modul tersebut jarang memiliki ketergantungan lebih lanjut. Tetapi tampaknya mengejek hampir secara definisi diperlukan untuk mengisolasi setiap modul di atas terbawah.

Dengan semua ini, adakah yang bisa memberi tahu saya apa yang mungkin hilang? Apakah tim kita terlalu sering mengejek? Atau mungkin ada beberapa asumsi dalam pedoman pengujian unit tipikal bahwa lapisan ketergantungan pada sebagian besar aplikasi akan cukup dangkal sehingga memang masuk akal untuk menguji semua modul kode yang diintegrasikan bersama-sama (menjadikan case kami "istimewa")? Atau mungkin secara berbeda, apakah tim kita tidak membatasi konteks kita dengan baik?

ardave
sumber
Bagi saya sepertinya aplikasi Anda dapat memanfaatkan kopling yang lebih longgar. en.wikipedia.org/wiki/Loose_coupling
Robert Harvey
1
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")? <- Ini.
Robert Harvey
Juga patut dicatat: Tujuan dari uji regresi (terutama pengujian integrasi) adalah untuk membuktikan bahwa perangkat lunak Anda masih berfungsi, tidak perlu mengidentifikasi di mana ia rusak. Anda dapat melakukannya dengan pemecahan masalah, memperbaiki masalah, dan kemudian menutupi kerusakan spesifik dengan tes unit tambahan.
Robert Harvey
Seharusnya saya lebih jelas dalam posting asli, untuk mengatakan bahwa modul 1 hanya menyadari I2, I3, dan I4. Modul 2 hanya mengetahui I5, I6, dan I7. Hanya tujuan pengujian yang dipertanyakan tanpa menggunakan tiruan yang akan saya berikan beton 2, 3 dan 4 ke 1, yang mengarah ke tantangan yang saya jelaskan. Kalau tidak, kita berakhir dengan mengolok-olok jauh lebih dari 5% dari waktu.
ardave
Saya agak bercanda tentang kasus kami menjadi "istimewa" setelah membaca posting blog tentang banyak tim yang menentang konvensi yang berharga karena mereka salah merasa situasi mereka "istimewa." Tetapi jika ini benar-benar kasus kami, ini akan menjelaskan perbedaan antara beberapa panduan komunitas yang telah saya baca, dan beberapa pengalaman aktual tim saya. (5% vs 70-90%)
ardave

Jawaban:

4

Apakah tim kita terlalu sering mengejek?

Tidak sekilas.

Jika Anda memiliki 1..13 modul, maka masing-masing harus memiliki unit test sendiri, dan semua dependensi (non-sepele, tidak dipercaya) harus diganti oleh versi tes. Itu bisa berarti mengolok-olok, tetapi beberapa orang jagoan dengan penamaan, jadi palsu, shims, objek nol ... beberapa orang menyebut semua implementasi pengujian sebagai "mengolok-olok". Ini mungkin menjadi sumber kebingungan tentang berapa "benar".

Secara pribadi, saya hanya menyebut semua benda uji "mengolok-olok" karena membedakan antara berbagai benda tersebut seringkali tidak berguna. Selama mereka menjaga unit test saya cepat, terisolasi dan tangguh ... Saya tidak peduli apa namanya.

Telastyn
sumber
Saya akan bertanya-tanya kemudian jika ada setiap pedoman umum di luar sana untuk saat yang terbaik adalah modul kode uji dalam isolasi vs pengujian lebih dari satu modul kode, terintegrasi bersama. Sepertinya begitu saya mengintegrasikan dua modul yang seharusnya bisa saya isolasi, saya membuka diri ke sejumlah masalah yang tidak diinginkan: Kurangnya menunjukkan dengan tepat penyebab regresi / beberapa tes gagal untuk satu regresi, pengaturan tes yang berlebihan, dll. Saya memiliki naluri intuisi saya sendiri ("dengarkan tes") tetapi ini membuat saya berada pada level tiruan 70-90%.
ardave
1
@ nono - Dalam pengalaman saya, Anda harus menguji semuanya secara terpisah, untuk alasan yang Anda sebutkan. Satu-satunya hal yang Anda tidak melakukan tes unit isolasi adalah hal yang tidak bisa karena mereka melawan beberapa file sistem atau sumber daya eksternal lainnya langsung ( sesuatu yang harus melakukan itu setelah semua).
Telastyn
Setelah mengunyah ini selama beberapa hari, penjelasan Anda sepertinya adalah penjelasan terbaik: Jika seseorang menggunakan definisi ketat "mengejek" sebagai jenis tes ganda yang digunakan untuk interaksi retrospektif / verifikasi perilaku, sebagai lawan dari tes dummy ganda atau tes ganda yang dikonfigurasi terlebih dahulu untuk mensimulasikan beberapa perilaku tertentu, maka ya, saya bisa melihat penutupan di level 5%.
ardave