Apa sekolah TDD London dan Chicago?

88

Saya telah mendengar tentang gaya London vs gaya Chicago (kadang-kadang disebut gaya Detroit) dari Test Driven Development (TDD).

Workshop Kelompok Pengguna Pemrograman Ekstrim Utah:

Gaya interaksi TDD juga disebut gaya mockist , atau gaya London setelah klub London Extreme London di mana ia menjadi populer. Biasanya kontras dengan gaya Detroit atau TDD klasik yang lebih berbasis negara.

Workshop Jason Gorman :

Lokakarya ini mencakup sekolah Chicago TDD (pengujian perilaku dan triangulasi berbasis negara), dan sekolah London , yang lebih berfokus pada pengujian interaksi, mengejek dan TDD end-to-end, dengan penekanan khusus pada Desain yang Didorong oleh Tanggung Jawab dan Desain . Tell, Don't Ask, pendekatan OO yang baru-baru ini dipopulerkan kembali oleh buku tumbuh-berkembang yang sangat baik oleh Steve Freeman dan Nat Pryce yang dipandu oleh Buku Panduan.

Tulisan TDD Klasik atau "London School"? oleh Jason Gorman sangat membantu, tetapi contoh-contohnya membingungkan saya, karena dia menggunakan dua contoh berbeda alih-alih satu contoh dengan kedua pendekatan. Apa perbedaannya? Kapan Anda menggunakan setiap gaya?

Arturo Herrero
sumber

Jawaban:

76

Misalkan Anda memiliki kelas yang disebut "buku besar" metode yang disebut "menghitung" yang menggunakan "Kalkulator" untuk melakukan berbagai jenis perhitungan tergantung pada argumen yang diteruskan ke "menghitung", misalnya "multiply (x, y)" atau "kurangi ( x, y) ".

Sekarang, misalkan Anda ingin menguji apa yang terjadi ketika Anda memanggil ledger.calculate ("5 * 7").

London / Sekolah Interaksi akan membuat Anda menegaskan apakah Calculator.multiply (5,7) dipanggil. Berbagai kerangka kerja mengejek berguna untuk ini, dan ini bisa sangat berguna jika, misalnya, Anda tidak memiliki kepemilikan objek "Kalkulator" (misalkan komponen atau layanan eksternal yang tidak dapat Anda uji langsung, tetapi Anda melakukannya tahu Anda harus menelepon dengan cara tertentu).

Sekolah Chicago / Negara Bagian akan meminta Anda untuk menegaskan apakah hasilnya adalah 35. Kerangka kerja jUnit / nUnit pada umumnya diarahkan untuk melakukan hal ini.

Keduanya adalah tes yang valid dan penting.

Matthew Flynn
sumber
Contoh yang sangat bagus.
sevenseacat
1
Saya akan menambahkan beberapa alasan lagi untuk menggunakan masing-masing: Jika yang penting adalah menentukan bahwa sesuatu telah atau belum berubah berdasarkan tindakan yang diambil (mis. Ledger.bucket.value menjadi 35 ketika ledger.calculate ("5 * 7 ") dipanggil), Anda ingin menggunakan pernyataan negara (sekolah Chicago). Ini sangat membantu ketika Anda memiliki kontrol penuh atas keadaan sistem sebelum metode dipanggil, dan ketika Anda benar-benar mengontrol apa yang dilakukan metode tersebut.
Matthew Flynn
1
Jika yang penting adalah mengetahui bahwa metode kedua disebut (misalnya, Calculator.multiply (5, 7)), Anda ingin menggunakan pernyataan aktivitas, seperti melalui objek tiruan. Ini sangat membantu jika metode yang dipanggil memiliki efek samping yang diinginkan (misalnya, menyimpan data, menambah penghitung, mengirim pesan, dll.) Jika Anda tidak benar-benar mengontrol apa yang dilakukan metode ini, sehingga nilai pengembalian mungkin tidak konsisten . Juga, jika Anda tidak dapat dengan mudah mengontrol keadaan sistem, yang terbaik yang dapat Anda lakukan adalah menentukan kegiatan apa yang terjadi.
Matthew Flynn
Pendekatan London berguna ketika kelas Kalkulator berpotensi berjalan lama karena alasan tertentu, atau melibatkan jaringan sehingga mungkin flakey dalam pengaturan dev / qa. Yaitu mengejek memungkinkan tes Anda menjadi cepat dan dapat diandalkan dalam kasus di mana itu tidak mungkin dilakukan.
Kevin
1
Pendekatan London juga berpendapat untuk memberikan sinyal umpan balik yang lebih jelas, karena jika Calculatormundur multiply, Anda akan melihat dua tes gagal: tes buku besar, dan tes kalkulator, tetapi hanya satu tes gagal jika Anda mengejek kalkulator. Itu mungkin membuatnya lebih mudah untuk menentukan asal bug, terutama jika sistemnya kompleks.
Matthias
30

Artikel Mocks Aron't Stubs , oleh Martin Fowler adalah pengantar yang bagus untuk topik ini.

Bergantung pada gaya desain yang Anda pilih (dan prinsip-prinsip desain tempat Anda membangun program Anda), setidaknya ada dua cara untuk melihat objek:

  1. Sebagai unit yang melakukan perhitungan berdasarkan input. Sebagai hasil dari perhitungan ini, objek dapat mengembalikan nilai atau mengubah kondisinya.
  2. Sebagai elemen aktif yang berkomunikasi dengan elemen lain dalam sistem dengan menyampaikan pesan.

Dalam kasus pertama, Anda tertarik pada apa yang keluar dari pemrosesan atau di mana status objek ditinggalkan setelah pemrosesan itu. Di sinilah metode seperti assertEquals()memasukkan gambar. Dalam hal ini, tidak masalah apa objek lain yang terlibat dalam pemrosesan, metode apa yang dipanggil, dll. Jenis verifikasi ini disebut verifikasi berbasis negara dan merupakan gaya "klasik".

Dalam kasus kedua, karena sebagian besar objek bahkan tidak mengembalikan hasil apa pun (misalnya voidmetode di Jawa), Anda lebih tertarik pada bagaimana objek berkomunikasi satu sama lain dan jika mereka menyampaikan pesan yang benar dalam keadaan yang ditentukan oleh tes. Interaksi ini biasanya diverifikasi dengan bantuan kerangka kerja tiruan. Verifikasi semacam ini disebut verifikasi berbasis perilaku atau berbasis interaksi. Salah satu implikasinya adalah teknik yang disebut Behavior Driven Development, di mana Anda mengembangkan kelas dengan asumsi bahwa kolaboratornya sudah ada (meskipun mereka mungkin belum ada), sehingga Anda dapat membuat kode terhadap antarmuka mereka.

Perhatikan bahwa ini bukan pilihan salah satu / atau. Anda dapat memiliki gaya desain yang memadukan kedua pendekatan untuk mendapatkan yang terbaik dari masing-masing pendekatan.

Otavio Macedo
sumber