Kode duplikat adalah bau dalam kode uji unit seperti halnya kode lainnya. Jika Anda memiliki kode duplikat dalam pengujian, akan lebih sulit untuk memfaktorkan ulang kode implementasi karena Anda memiliki jumlah pengujian yang tidak proporsional untuk diperbarui. Tes akan membantu Anda refactor dengan percaya diri, daripada menjadi beban besar yang menghambat pekerjaan Anda pada kode yang sedang diuji.
Jika duplikasi dalam pengaturan fixture, pertimbangkan untuk menggunakan lebih banyak setUp
metode atau menyediakan Metode Penciptaan yang lebih (atau lebih fleksibel) .
Jika duplikasi ada dalam kode yang memanipulasi SUT, tanyakan pada diri Anda mengapa beberapa pengujian yang disebut "unit" melakukan fungsi yang sama persis.
Jika duplikasi ada dalam pernyataan, mungkin Anda memerlukan beberapa Pernyataan Khusus . Misalnya, jika beberapa pengujian memiliki serangkaian pernyataan seperti:
assertEqual('Joe', person.getFirstName())
assertEqual('Bloggs', person.getLastName())
assertEqual(23, person.getAge())
Maka mungkin Anda membutuhkan satu assertPersonEqual
metode, agar Anda bisa menulis assertPersonEqual(Person('Joe', 'Bloggs', 23), person)
. (Atau mungkin Anda hanya perlu membebani operator kesetaraan Person
.)
Seperti yang Anda sebutkan, penting agar kode pengujian dapat dibaca. Secara khusus, penting agar tujuan pengujian jelas. Saya menemukan bahwa jika banyak tes terlihat sebagian besar sama, (misalnya tiga perempat garis sama atau hampir sama) sulit untuk menemukan dan mengenali perbedaan yang signifikan tanpa membaca dan membandingkannya dengan cermat. Jadi saya menemukan bahwa refactoring untuk menghapus duplikasi membantu keterbacaan, karena setiap baris dari setiap metode pengujian secara langsung relevan dengan tujuan pengujian. Itu jauh lebih berguna bagi pembaca daripada kombinasi acak dari garis yang secara langsung relevan, dan garis yang hanya berupa pelat standar.
Meskipun demikian, terkadang pengujian menggunakan situasi kompleks yang serupa tetapi masih sangat berbeda, dan sulit untuk menemukan cara yang baik untuk mengurangi duplikasi. Gunakan akal sehat: jika Anda merasa pengujian dapat dibaca dan memperjelas maksudnya, dan Anda merasa nyaman mungkin perlu memperbarui lebih dari jumlah pengujian yang secara teoritis minimal saat memfaktorkan ulang kode yang dipanggil oleh pengujian, maka terima ketidaksempurnaan tersebut dan lanjutkan ke sesuatu yang lebih produktif. Anda selalu dapat kembali dan memfaktorkan ulang pengujian nanti, saat inspirasi muncul!
Keterbacaan lebih penting untuk tes. Jika tes gagal, Anda ingin masalahnya jelas. Pengembang tidak harus melewati banyak kode pengujian yang sangat difaktorkan untuk menentukan dengan tepat apa yang gagal. Anda tidak ingin kode pengujian menjadi begitu rumit sehingga Anda perlu menulis unit-test-test.
Namun, menghilangkan duplikasi biasanya merupakan hal yang baik, selama itu tidak mengaburkan apapun, dan menghilangkan duplikasi dalam pengujian Anda dapat menghasilkan API yang lebih baik. Pastikan Anda tidak melewati titik pengembalian yang semakin berkurang.
sumber
Kode implementasi dan pengujian adalah hewan yang berbeda dan aturan pemfaktoran berlaku berbeda untuk mereka.
Kode atau struktur duplikat selalu menjadi bau dalam kode implementasi. Saat Anda mulai menerapkan boilerplate, Anda perlu merevisi abstraksi Anda.
Di sisi lain, kode pengujian harus mempertahankan tingkat duplikasi. Duplikasi dalam kode pengujian mencapai dua tujuan:
Saya cenderung mengabaikan duplikasi sepele dalam kode pengujian selama setiap metode pengujian tetap lebih pendek dari sekitar 20 baris. Saya suka ketika ritme setup-run-verifikasi terlihat jelas dalam metode pengujian.
Saat duplikasi merayap di bagian "verifikasi" pada pengujian, sering kali bermanfaat untuk menentukan metode pernyataan kustom. Tentu saja, metode-metode tersebut masih harus menguji relasi yang teridentifikasi dengan jelas yang dapat diperlihatkan dalam nama metode:
assertPegFitsInHole
-> baik,assertPegIsGood
-> buruk.Ketika metode pengujian bertambah panjang dan berulang, terkadang saya merasa berguna untuk menentukan template pengujian fill-in-the-blanks yang mengambil beberapa parameter. Kemudian metode pengujian yang sebenarnya direduksi menjadi panggilan ke metode template dengan parameter yang sesuai.
Adapun banyak hal dalam pemrograman dan pengujian, tidak ada jawaban yang jelas. Anda perlu mengembangkan selera, dan cara terbaik untuk melakukannya adalah dengan membuat kesalahan.
sumber
Saya setuju. Pertukaran itu ada tetapi berbeda di tempat yang berbeda.
Saya lebih cenderung memfaktor ulang kode duplikat untuk menyiapkan status. Tapi kecil kemungkinannya untuk merefaktor bagian dari pengujian yang benar-benar melatih kode. Yang mengatakan, jika menjalankan kode selalu membutuhkan beberapa baris kode maka saya mungkin berpikir itu adalah bau dan refactor kode sebenarnya yang diuji. Dan itu akan meningkatkan keterbacaan dan pemeliharaan kode dan tes.
sumber
Anda dapat mengurangi pengulangan menggunakan beberapa jenis metode utilitas pengujian .
Saya lebih toleran terhadap pengulangan dalam kode pengujian daripada dalam kode produksi, tetapi saya terkadang frustrasi karenanya. Ketika Anda mengubah desain kelas dan Anda harus kembali dan mengubah 10 metode pengujian berbeda yang semuanya melakukan langkah-langkah penyiapan yang sama, itu membuat frustrasi.
sumber
Jay Fields menciptakan frasa bahwa "DSL harus DAMP, bukan KERING", di mana DAMP berarti frasa deskriptif dan bermakna . Saya pikir hal yang sama juga berlaku untuk tes. Jelas, terlalu banyak duplikasi itu buruk. Tetapi menghapus duplikasi dengan cara apa pun bahkan lebih buruk. Pengujian harus bertindak sebagai spesifikasi yang mengungkapkan maksud. Jika, misalnya, Anda menentukan fitur yang sama dari beberapa sudut yang berbeda, maka diharapkan ada sejumlah duplikasi.
sumber
I LOVE rspec karena ini:
Ada 2 hal untuk membantu -
kelompok contoh bersama untuk menguji perilaku umum.
Anda dapat menentukan serangkaian pengujian, lalu 'memasukkan' set tersebut ke dalam pengujian Anda yang sebenarnya.
konteks bersarang.
Anda pada dasarnya dapat memiliki metode 'setup' dan 'teardown' untuk subset tertentu dari pengujian Anda, tidak hanya setiap orang di kelas.
Semakin cepat .NET / Java / framework pengujian lainnya mengadopsi metode ini, semakin baik (atau Anda dapat menggunakan IronRuby atau JRuby untuk menulis pengujian Anda, yang menurut saya pribadi adalah opsi yang lebih baik)
sumber
Saya merasa bahwa kode pengujian memerlukan tingkat rekayasa serupa yang biasanya diterapkan pada kode produksi. Pasti ada argumen yang mendukung keterbacaan dan saya setuju itu penting.
Namun, menurut pengalaman saya, saya menemukan bahwa tes yang difaktorkan dengan baik lebih mudah dibaca dan dipahami. Jika ada 5 pengujian yang masing-masing terlihat sama kecuali untuk satu variabel yang diubah dan pernyataan di bagian akhir, akan sangat sulit untuk menemukan item yang berbeda tersebut. Demikian pula, jika difaktorkan sehingga hanya variabel yang berubah yang terlihat dan pernyataannya, maka mudah untuk mengetahui apa yang segera dilakukan pengujian.
Menemukan tingkat abstraksi yang tepat saat pengujian bisa jadi sulit dan saya rasa itu layak dilakukan.
sumber
Saya tidak berpikir ada hubungan antara kode yang lebih digandakan dan dapat dibaca. Saya pikir kode pengujian Anda harus sebagus kode Anda yang lain. Kode yang tidak berulang lebih mudah dibaca daripada kode yang digandakan jika dilakukan dengan baik.
sumber
Idealnya, pengujian unit tidak boleh banyak berubah setelah ditulis jadi saya akan condong ke arah keterbacaan.
Membuat pengujian unit menjadi sesederhana mungkin juga membantu menjaga pengujian tetap fokus pada fungsi spesifik yang mereka targetkan.
Karena itu, saya cenderung mencoba dan menggunakan kembali potongan kode tertentu yang akhirnya saya gunakan berulang kali, seperti kode penyiapan yang persis sama di seluruh rangkaian pengujian.
sumber
"memfaktorkan ulang mereka agar lebih KERING - maksud dari setiap tes tidak lagi jelas"
Sepertinya Anda kesulitan melakukan refactoring. Saya hanya menebak-nebak, tetapi jika hasilnya kurang jelas, bukankah itu berarti Anda masih memiliki lebih banyak pekerjaan yang harus dilakukan sehingga Anda memiliki tes yang cukup elegan yang sangat jelas?
Itulah mengapa pengujian merupakan subkelas dari UnitTest - sehingga Anda dapat merancang rangkaian pengujian yang tepat, mudah divalidasi, dan jelas.
Di masa lalu kami memiliki alat pengujian yang menggunakan bahasa pemrograman yang berbeda. Sulit (atau tidak mungkin) untuk mendesain menyenangkan, mudah dikerjakan dengan tes.
Anda memiliki kekuatan penuh - bahasa apa pun yang Anda gunakan - Python, Java, C # - jadi gunakan bahasa itu dengan baik. Anda dapat memperoleh kode pengujian yang bagus dan jelas dan tidak terlalu berlebihan. Tidak ada trade-off.
sumber