tl; dr
Di Pivotal kami menulis Cedar karena kami menggunakan dan menyukai Rspec pada proyek Ruby kami. Cedar tidak dimaksudkan untuk menggantikan atau bersaing dengan OCUnit; itu dimaksudkan untuk membawa kemungkinan pengujian gaya BDD ke Objective C, seperti Rspec memelopori pengujian gaya BDD di Ruby, tetapi belum menghilangkan Uji :: Unit. Memilih satu atau yang lain sebagian besar adalah masalah preferensi gaya.
Dalam beberapa kasus kami merancang Cedar untuk mengatasi beberapa kekurangan dalam cara OCUnit bekerja untuk kami. Secara khusus, kami ingin dapat menggunakan debugger dalam pengujian, untuk menjalankan tes dari baris perintah dan dalam build CI, dan mendapatkan hasil teks yang berguna dari hasil pengujian. Hal-hal ini mungkin lebih atau kurang bermanfaat bagi Anda.
Jawaban panjang
Memutuskan antara dua kerangka kerja pengujian seperti Cedar dan OCUnit (misalnya) bermuara pada dua hal: gaya yang disukai, dan kemudahan penggunaan. Saya akan mulai dengan gaya, karena itu hanya masalah pendapat dan preferensi; kemudahan penggunaan cenderung menjadi satu set pengorbanan.
Pertimbangan gaya melampaui teknologi atau bahasa apa yang Anda gunakan. xUnit unit-style telah ada jauh lebih lama dari pengujian style-BDD, tetapi yang terakhir telah dengan cepat memperoleh popularitas, sebagian besar karena Rspec.
Keuntungan utama pengujian gaya xUnit adalah kesederhanaannya, dan adopsi yang luas (di antara pengembang yang menulis tes unit); hampir semua bahasa yang dapat Anda pertimbangkan untuk menulis kode memiliki kerangka kerja gaya xUnit yang tersedia.
Kerangka kerja gaya BDD cenderung memiliki dua perbedaan utama bila dibandingkan dengan gaya xUnit: bagaimana Anda menyusun tes (atau spesifikasi), dan sintaksis untuk menulis pernyataan Anda. Bagi saya, perbedaan struktural adalah pembeda utama. xUnit tes satu dimensi, dengan satu metode setUp untuk semua tes dalam kelas tes yang diberikan. Kelas yang kami uji, bagaimanapun, bukan satu dimensi; kita sering perlu menguji tindakan dalam beberapa konteks yang berbeda, berpotensi saling bertentangan. Misalnya, pertimbangkan kelas ShoppingCart sederhana, dengan metode addItem: (untuk keperluan jawaban ini saya akan menggunakan sintaks Objective C). Perilaku metode ini mungkin berbeda ketika kereta kosong dibandingkan dengan ketika kereta berisi barang-barang lainnya; mungkin berbeda jika pengguna telah memasukkan kode diskon; mungkin berbeda jika item yang ditentukan bisa ' t dikirim dengan metode pengiriman yang dipilih; dll. Ketika kondisi-kondisi yang mungkin ini bersilangan satu sama lain, Anda berakhir dengan jumlah konteks yang meningkat secara geometris; dalam pengujian xUnit-style, ini sering mengarah ke banyak metode dengan nama-nama seperti testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktur kerangka kerja gaya BDD memungkinkan Anda untuk mengatur kondisi ini secara individual, yang menurut saya membuatnya lebih mudah untuk memastikan saya menutupi semua kasus, serta lebih mudah untuk menemukan, mengubah, atau menambahkan kondisi individual. Sebagai contoh, menggunakan sintaks Cedar, metode di atas akan terlihat seperti ini: dalam pengujian xUnit-style, ini sering mengarah ke banyak metode dengan nama-nama seperti testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktur kerangka kerja gaya BDD memungkinkan Anda untuk mengatur kondisi ini secara individual, yang menurut saya membuatnya lebih mudah untuk memastikan saya menutupi semua kasus, serta lebih mudah untuk menemukan, mengubah, atau menambahkan kondisi individual. Sebagai contoh, menggunakan sintaks Cedar, metode di atas akan terlihat seperti ini: dalam pengujian xUnit-style, ini sering mengarah ke banyak metode dengan nama-nama seperti testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktur kerangka kerja gaya BDD memungkinkan Anda untuk mengatur kondisi ini secara individual, yang menurut saya membuatnya lebih mudah untuk memastikan saya menutupi semua kasus, serta lebih mudah untuk menemukan, mengubah, atau menambahkan kondisi individual. Sebagai contoh, menggunakan sintaks Cedar, metode di atas akan terlihat seperti ini:
describe(@"ShoppingCart", ^{
describe(@"addItem:", ^{
describe(@"when the cart is empty", ^{
describe(@"with no discount code", ^{
describe(@"when the shipping method applies to the item", ^{
it(@"should add the item to the cart", ^{
...
});
it(@"should add the full price of the item to the overall price", ^{
...
});
});
describe(@"when the shipping method does not apply to the item", ^{
...
});
});
describe(@"with a discount code", ^{
...
});
});
describe(@"when the cart contains other items, ^{
...
});
});
});
Dalam beberapa kasus, Anda akan menemukan konteks di dalamnya yang berisi set asersi yang sama, yang dapat Anda KERING menggunakan konteks contoh bersama.
Perbedaan utama kedua antara kerangka kerja gaya-BDD dan kerangka kerja gaya-xUnit, pernyataan (atau "matcher") sintaksis, membuat gaya spesifikasi agak lebih baik; beberapa orang sangat menyukainya, yang lain tidak.
Itu mengarah pada pertanyaan tentang kemudahan penggunaan. Dalam hal ini, setiap kerangka kerja memiliki pro dan kontra:
OCUnit telah ada jauh lebih lama dari Cedar, dan terintegrasi langsung ke dalam Xcode. Ini berarti mudah untuk membuat target pengujian baru, dan, sebagian besar waktu, mendapatkan tes dan menjalankan "hanya berfungsi." Di sisi lain, kami menemukan bahwa dalam beberapa kasus, seperti berjalan di perangkat iOS, menjalankan tes OCUnit hampir mustahil. Menyiapkan spesifikasi Cedar membutuhkan lebih banyak pekerjaan daripada tes OCUnit, karena Anda telah mendapatkan pustaka dan menautkannya sendiri (tidak pernah merupakan tugas sepele di Xcode). Kami sedang berupaya membuat pengaturan lebih mudah, dan semua saran lebih dari diterima.
OCUnit menjalankan tes sebagai bagian dari build. Ini berarti Anda tidak perlu menjalankan executable untuk menjalankan tes Anda; jika ada tes yang gagal, build Anda gagal. Ini membuat proses menjalankan tes satu langkah lebih mudah, dan output tes langsung masuk ke jendela output build Anda yang membuatnya mudah dilihat. Kami memilih untuk membuat spesifikasi Cedar menjadi executable yang Anda jalankan secara terpisah karena beberapa alasan:
- Kami ingin dapat menggunakan debugger. Anda menjalankan spesifikasi Cedar sama seperti Anda akan menjalankan executable lainnya, sehingga Anda dapat menggunakan debugger dengan cara yang sama.
- Kami ingin konsol mudah masuk dalam tes. Anda dapat menggunakan NSLog () dalam tes OCUnit, tetapi output masuk ke jendela build di mana Anda harus membuka langkah build untuk membacanya.
- Kami ingin mudah membaca laporan pengujian, baik di baris perintah maupun di Xcode. Hasil OCUnit muncul dengan baik di jendela build di Xcode, tetapi membangun dari baris perintah (atau sebagai bagian dari proses CI) menghasilkan output tes yang bercampur dengan banyak dan banyak output build lainnya. Dengan fase build dan run yang terpisah, Cedar memisahkan output sehingga output tes mudah ditemukan. Pelari uji Cedar default menyalin gaya pencetakan standar "." untuk setiap spesifikasi yang lewat, "F" untuk spesifikasi yang gagal, dll. Cedar juga memiliki kemampuan untuk menggunakan objek reporter khusus, sehingga Anda dapat memperoleh hasil keluaran sesuai keinginan Anda, dengan sedikit usaha.
OCUnit adalah kerangka pengujian unit resmi untuk Objective C, dan didukung oleh Apple. Apple pada dasarnya memiliki sumber daya tanpa batas, jadi jika mereka ingin sesuatu dilakukan, itu akan selesai. Dan, bagaimanapun juga, ini adalah kotak pasir Apple tempat kami bermain. Sisi lain dari koin itu, bagaimanapun, adalah bahwa Apple menerima pesanan permintaan dukungan bajillion dan laporan bug setiap hari. Mereka sangat baik dalam menangani semuanya, tetapi mereka mungkin tidak dapat menangani masalah yang Anda laporkan segera, atau tidak sama sekali. Cedar jauh lebih baru dan kurang dipanggang daripada OCUnit, tetapi jika Anda memiliki pertanyaan atau masalah atau saran, kirim pesan ke milis Cedar (cedar-discuss@googlegroups.com) dan kami akan melakukan apa yang kami bisa untuk membantu Anda. Juga, jangan ragu untuk mengambil kode dari Github (github.com/pivotal/cedar) dan tambahkan apa pun yang menurut Anda tidak ada.
Menjalankan tes OCUnit pada perangkat iOS mungkin sulit. Sejujurnya, saya belum mencoba ini selama beberapa waktu, jadi mungkin menjadi lebih mudah, tetapi terakhir kali saya mencoba saya tidak bisa mendapatkan tes OCUnit untuk fungsionalitas UIKit agar berfungsi. Ketika kami menulis Cedar, kami memastikan bahwa kami dapat menguji kode yang bergantung pada UIKit baik pada simulator maupun pada perangkat.
Akhirnya, kami menulis Cedar untuk pengujian unit, yang berarti tidak benar-benar sebanding dengan proyek-proyek seperti UISpec. Sudah cukup lama sejak saya mencoba menggunakan UISpec, tetapi saya memahaminya untuk fokus terutama pada pemrograman terprogram UI pada perangkat iOS. Kami secara khusus memutuskan untuk tidak mencoba agar Cedar mendukung jenis spesifikasi ini, karena Apple (pada saat itu) akan mengumumkan UIAutomation.