Dalam ceramahnya TDD, di mana semuanya salah , Ian Cooper mendorong niat asli Kent Beck di balik pengujian unit dalam TDD (untuk menguji perilaku, bukan metode kelas khusus) dan berpendapat untuk menghindari menggabungkan tes untuk implementasi.
Dalam hal perilaku seperti save X to some data source
dalam sistem dengan seperangkat layanan dan repositori yang khas, bagaimana kita dapat menguji unit penyimpanan beberapa data pada tingkat layanan, melalui repositori, tanpa menyambungkan tes ke detail implementasi (seperti memanggil metode tertentu )? Apakah menghindari sambungan semacam ini sebenarnya tidak sepadan dengan usaha / buruk dalam beberapa cara?
unit-testing
tdd
coupling
Andy Hunt
sumber
sumber
Jawaban:
Contoh spesifik Anda adalah kasus yang biasanya harus Anda uji dengan memeriksa apakah metode tertentu dipanggil, karena
saving X to data source
berarti berkomunikasi dengan ketergantungan eksternal , sehingga perilaku yang harus Anda uji adalah bahwa komunikasi tersebut terjadi seperti yang diharapkan .Namun, ini bukan hal yang buruk. Antarmuka batas antara aplikasi Anda dan dependensi eksternalnya bukan detail implementasi , pada kenyataannya, mereka didefinisikan dalam arsitektur sistem Anda; yang berarti bahwa batas seperti itu tidak akan berubah (atau jika harus, itu akan menjadi jenis perubahan yang paling jarang). Dengan demikian, menggabungkan tes Anda ke
repository
antarmuka seharusnya tidak menyebabkan Anda terlalu banyak kesulitan (jika ya, pertimbangkan apakah antarmuka tersebut tidak mencuri tanggung jawab dari aplikasi).Sekarang, pertimbangkan hanya aturan bisnis aplikasi, dipisahkan dari UI, database, dan layanan eksternal lainnya. Ini adalah Anda harus bebas untuk mengubah struktur dan perilaku kode. Di sinilah pengujian kopling dan detail implementasi akan memaksa Anda untuk mengubah lebih banyak kode uji daripada kode produksi, bahkan ketika tidak ada perubahan dalam perilaku keseluruhan aplikasi. Di sinilah pengujian
State
bukannyaInteraction
membantu kami lebih cepat.PS: Bukan maksud saya untuk mengatakan apakah pengujian oleh Negara atau Interaksi adalah satu-satunya cara yang sebenarnya dari TDD - saya percaya itu masalah menggunakan alat yang tepat untuk pekerjaan yang tepat.
sumber
Penafsiran saya tentang pembicaraan itu adalah:
Itu tidak disebutkan dalam pembicaraan, tetapi saya pikir konteks yang diasumsikan untuk saran adalah sesuatu seperti:
Jadi pengujian komponen adalah ruang lingkup terbesar yang mungkin di mana sesuatu masih bisa disebut unit testing. Ini agak berbeda dengan bagaimana beberapa orang, terutama akademisi, menggunakan istilah ini. Ini tidak seperti contoh dalam tutorial alat uji unit tipikal. Namun, itu cocok dengan asalnya dalam pengujian perangkat keras; papan dan modul adalah unit yang diuji, bukan kabel dan sekrup. Atau setidaknya Anda tidak membuat Boeing tiruan untuk menguji sekrup ...
Mengekstrapolasi dari itu, dan memasukkan beberapa pemikiran saya sendiri,
Jika Anda melakukannya dengan benar dan bersih, Anda hampir tidak memerlukan alat mengejek; itu hanya digunakan beberapa kali per sistem.
Database umumnya kolaborator, sehingga dipalsukan daripada diejek. Ini akan menyakitkan untuk diterapkan dengan tangan; Untungnya hal-hal seperti itu sudah ada .
Pola pengujian dasar adalah melakukan beberapa urutan operasi (mis. Menyimpan dan memuat kembali dokumen); konfirmasi itu berfungsi. Ini sama dengan skenario pengujian lainnya; tidak ada perubahan implementasi (yang berfungsi) yang kemungkinan menyebabkan tes seperti itu gagal.
Pengecualian adalah di mana catatan database ditulis tetapi tidak pernah dibaca oleh sistem yang diuji; mis. log audit atau sejenisnya. Ini adalah output, dan karenanya harus diejek. Pola pengujian adalah melakukan beberapa urutan operasi; konfirmasi antarmuka audit dipanggil dengan metode dan argumen sebagaimana ditentukan.
Perhatikan bahwa bahkan di sini, asalkan Anda menggunakan alat mengejek tipe-aman seperti mockito , mengganti nama metode antarmuka tidak dapat menyebabkan kegagalan pengujian. Jika Anda menggunakan IDE dengan tes yang dimuat, itu akan menjadi refactored bersama dengan metode rename. Jika tidak, tes tidak akan dikompilasi.
sumber
Saran saya adalah menggunakan pendekatan pengujian berbasis negara:
DIBERIKAN Kami memiliki tes DB dalam kondisi yang diketahui
KAPAN Layanan disebut dengan argumen X
KEMUDIAN Menegaskan bahwa DB telah berubah dari keadaan semula ke keadaan yang diharapkan dengan memanggil metode repositori read-only dan memeriksa nilai yang dikembalikan
Dengan melakukan itu, Anda tidak bergantung pada algoritme internal apa pun dari layanan ini, dan bebas untuk memperbaiki implementasinya tanpa harus mengubah tes.
Satu-satunya sambungan di sini adalah panggilan metode layanan dan panggilan repositori yang diperlukan untuk membaca data dari DB, yang baik-baik saja.
sumber