Verifikasi panggilan tiruan TDD - apakah ini anti-pola?


11

Saya sudah melakukan TDD selama setahun sekarang, saya merasa cukup baik tentang itu, saya suka suite tes saya dan semuanya. Namun saya perhatikan bahwa belakangan ini saya telah melakukan banyak verifikasi panggilan palsu. Sebagai contoh, saya akan memiliki Layanan yang akan memiliki Repositori disuntikkan - dalam pengujian unit saya, saya akan lulus tiruan dari Repositori dan memverifikasi bahwa itu dipanggil dalam metode yang saya uji. Saya kemudian akan memeriksa apakah hasilnya dikembalikan benar (dalam tes lain). Ini pasti "terasa" salah, karena unit test saya sekarang sangat digabungkan dengan detail implementasi. Saya pernah mendengar bahwa Anda harus menguji "perilaku", namun dalam banyak situasi yang ... emm - tidak mungkin? Jika Anda punyavoidMetode misalnya, Anda biasanya menguji efek samping. Maksud saya mudah untuk terus maju dan menunjukkan beberapa kode-kata sederhana di mana ini dapat ditunjukkan, tetapi IMHO itu tidak mencerminkan dengan baik untuk program dunia nyata yang kita tulis. Apa yang saya lakukan salah? Apakah jenis pengujian semacam ini merupakan anti-pola? Saya menghargai pendapat Anda tentang ini, saya masih sedikit pemula dalam hal TDD.


2
Jawaban singkat: ya. Ada pertanyaan yang sangat menarik tentang topik ini di suatu tempat di sini. Tes unit Anda tidak boleh rapuh dan sangat bergantung pada implementasi Anda. Inilah sebabnya mengapa tes tingkat yang lebih tinggi adalah untuk (integrasi, dll.). Di sini: programmers.stackexchange.com/questions/198453/…
Kemoda

@EModa Saya sangat menghargainya jika Anda dapat menghubungkan saya ke diskusi atau beberapa materi lebih lanjut tentang ini, saya sangat ingin meningkatkan teknik saya.
Dimitar Dimitrov

1
Anda memiliki ini sebagai contoh programmers.stackexchange.com/questions/198453/... saya akan menemukan tautan lain nanti
Kemoda

Jawaban:


8

Nah, Anda harus mencoba menguji input dan output. Anda harus memverifikasi perilaku yang terlihat secara eksternal. "Janji" atau "kontrak" yang dibuat oleh kelas Anda.

Pada saat yang sama terkadang tidak ada cara yang lebih baik untuk menguji suatu metode selain melakukan apa yang Anda katakan.

Saya pikir itu membuat tes Anda lebih rapuh, jadi Anda harus menghindari tes yang bergantung pada detail implementasi jika Anda bisa, tetapi itu bukan kesepakatan semua-atau-tidak sama sekali. Tidak apa-apa terkadang, hal terburuk yang terjadi adalah Anda mengubah implementasi dan harus memperbarui tes.


2

Tujuan dari tes ini adalah untuk membatasi kemungkinan implementasi produktif. Pastikan Anda hanya membatasi implementasi yang benar-benar Anda butuhkan. Biasanya ini yang harus dilakukan oleh program Anda, dan bukan bagaimana melakukannya.

Jadi jika misalnya layanan Anda menambahkan sesuatu ke repositori, Anda harus menguji bahwa entri baru terkandung dalam repositori sesudahnya, dan bukan bahwa tindakan add dipicu.

Agar ini berfungsi, Anda harus dapat menggunakan implementasi repositori (diuji di tempat lain) dalam pengujian layanan. Saya menemukan bahwa menggunakan implementasi nyata dari kolaborator umumnya merupakan pendekatan yang baik - karena ini benar-benar implementasi terbaik.


"Jadi, tetapi bagaimana jika menggunakan implementasi nyata dalam tes itu mahal (misalnya karena mereka membutuhkan sumber daya yang rumit untuk diatur)? Saya perlu menggunakan ejekan dalam kasus ini, kan?"

Dalam kasus apa pun Anda mungkin ingin satu tes integrasi yang menguji bahwa implementasi nyata bekerja bersama. Pastikan hanya tes integrasi yang diperlukan untuk menguji layanan Anda. Atau dengan kata lain: Jika suatu layanan menghubungkan banyak kolaborator (dan karenanya berpotensi sulit untuk diuji), pastikan itu tidak mengandung logika apa pun. Jika ya, dan Anda perlu beberapa (integrasi) tes, Anda perlu mengubah struktur kode Anda, misalnya dengan mengisolasi logika dan karenanya membuatnya lebih dapat diuji.

Menggunakan ejekan dalam kasus ini memudahkan rasa sakit menguji sepotong logika yang sangat terisolasi, dan karenanya menyembunyikan masalah arsitektur . Jadi jangan gunakan tiruan untuk menguji kode yang terstruktur dengan buruk, tetapi perbaiki strukturnya.


1
Saya mengerti apa yang Anda katakan. Topik ini agak membingungkan untuk "berapa banyak pengujian terlalu banyak pengujian", katakanlah saya memiliki "layanan agregat" yang pada dasarnya adalah fasad dan hanya "menempelkan" sekumpulan layanan / repositori / komponen lain seperti tes apa apakah kamu menulis untuk itu? Yang bisa saya pikirkan hanyalah verifikasi panggilan. Saya harap saya masuk akal.
Dimitar Dimitrov

2

Pikiranku kembali: 'layanan agregat'.

Verifikasi panggilan akan melakukan ini, tetapi tidak akan memberikan banyak nilai. Anda hanya memeriksa kabel Anda.

Ada 3, non-eksklusif, cara lain untuk ini:

  1. Perpanjang tes yang Anda miliki untuk setiap layanan individual sehingga memeriksa perilaku tingkat yang lebih tinggi. Misalnya, jika Anda menekan basis data dalam memori di unit Anda menguji layanan, naikkan level sehingga Anda menguji layanan terhadap db yang sebenarnya. Lapisan layanan lebih tinggi pada pohon abstraksi, dan begitu juga tes Anda.

  2. Gunakan pembuatan kode untuk membuat layanan langsung dari layanan gabungan.

  3. Gunakan semacam refleksi atau bahasa dinamis untuk melakukan hal yang sama. Misalnya, di Jawa, dimungkinkan untuk menggunakan antarmuka asyik, yang meneruskan panggilan secara langsung.

Mungkin ada cara lain untuk melakukan ini, tetapi hanya memeriksa kabel memiliki pengembalian sangat rendah, dan akan menyulitkan Anda untuk implementasi ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.