Kode Tes Salin-dan-Tempel: Seberapa Buruk Ini?

12

Pekerjaan saya saat ini kebanyakan menulis kode uji GUI untuk berbagai aplikasi yang kami kerjakan. Namun, saya menemukan bahwa saya cenderung menyalin dan menempel banyak kode dalam pengujian. Alasan untuk ini adalah bahwa area yang saya uji cenderung cukup mirip sehingga perlu pengulangan tetapi tidak cukup mirip untuk merangkum kode ke dalam metode atau objek. Saya menemukan bahwa ketika saya mencoba menggunakan kelas atau metode lebih luas, tes menjadi lebih rumit untuk dipelihara dan kadang-kadang sulit untuk menulis.

Sebagai gantinya, saya biasanya menyalin sebagian besar kode uji dari satu bagian dan menempelnya ke bagian lain, dan membuat perubahan kecil yang saya butuhkan. Saya tidak menggunakan cara pengkodean yang lebih terstruktur, seperti menggunakan lebih banyak prinsip atau fungsi OO.

Apakah coders lain merasakan hal ini ketika menulis kode tes? Jelas saya ingin mengikuti prinsip KERING dan YAGNI, tetapi saya menemukan bahwa kode uji (kode uji otomatis untuk pengujian GUI) dapat membuat prinsip-prinsip ini sulit untuk diikuti. Atau apakah saya hanya perlu lebih banyak praktik pengkodean dan sistem keseluruhan yang lebih baik dalam melakukan sesuatu?

EDIT: Alat yang saya gunakan adalah SilkTest, yang dalam bahasa eksklusif disebut 4Test. Selain itu, tes ini sebagian besar untuk aplikasi desktop Windows, tetapi saya juga telah menguji aplikasi web menggunakan pengaturan ini juga.

joshin4colours
sumber
Alat uji apa yang Anda gunakan? Mungkin saja kerangka pengujian Anda tidak mendukung jenis tes yang Anda tulis. Cut-n-paste lebih dari 3 baris umumnya benar-benar buruk, tetapi jika Anda dapat dengan jelas menambahkan nilai jangka panjang dengan mengotomatisasi tes GUI daripada dengan melakukannya secara manual setiap waktu, maka apa pun yang Anda lakukan mungkin sangat terkutuk baik.
GlenPeterson
Juga, bahasa apa ini? Anda mungkin memiliki sesuatu yang tersedia yang tidak muncul dalam pikiran, yang memungkinkan penggunaan kembali (seperti fungsi kelas satu). Di sisi lain, kasus uji yang seharusnya dibuat sederhana, untuk tetap kecil kemungkinan mereka memiliki bug sendiri ...
Izkata
3
Dalam apa pun yang saya tulis, kode pengujian tidak dikecualikan dari refactoring ..
Simon Whitehead

Jawaban:

23

Copy-paste dan kemudian diedit kasus uji sering baik-baik saja.

Tes harus memiliki ketergantungan eksternal sesedikit mungkin, dan sejelas mungkin. Kasus uji cenderung berubah seiring waktu, dan kasus uji yang sebelumnya hampir identik mungkin tiba-tiba berbeda. Memperbarui satu test case tanpa harus khawatir akan memecahkan case lainnya adalah Good Thing.

Tentu saja, kode boilerplate yang identik dalam banyak kasus uji dan harus berubah dalam konser dapat dan harus diperhitungkan.

9000
sumber
1
Ini terutama bagaimana perasaanku. Kode tes yang hampir identik adalah ok dalam banyak kasus, tetapi kode tes yang sama berulang adalah berita buruk.
joshin4colours
12

Pengulangan adalah akar dari semua kejahatan

Itu benar! Pengulangan adalah akar dari semua kejahatan . Mungkin itu kata Knuth dalam bukunya "Optimalisasi prematur adalah akar dari semua kejahatan", tapi saya pikir itu adalah pengulangan.

Setiap kali Anda melihat suatu program atau Anda sedang menulis suatu program dan Anda menemukan semacam pengulangan: Hapus itu! Bunuh segera ... apa pun kecuali singkirkan !

Setiap kali saya memperkenalkan semacam pengulangan dan harus memperbaiki bug di sana, saya lupa untuk memperbaiki replika ... (Donald Knuth) Jadi, setiap kali ada pengulangan hapus saja sebaik mungkin, jangan hack !

Pikirkan desain lean bersih (seperti, merangkum blok kode berulang Anda di kelas pembantu) dan menulis beberapa tes sebelum mengubah sesuatu (hanya untuk memastikan Anda tidak merusak sesuatu). Ini berlaku untuk setiap bagian kode yang ditulis dan kode pengujian tidak terkecuali.

Berikut ini adalah bacaan yang baik dari Code Horror yang menginspirasi saya - Proposal Sederhana untuk Copy and Paste School of Code Reuse .

Yusubov
sumber
"Setiap kali saya memperkenalkan semacam pengulangan dan harus memperbaiki bug di sana, saya lupa untuk memperbaiki replika ..." tepatnya. Juga, jika Anda dapat & dan Anda lupa menyesuaikan teks yang disalin dengan konteks Anda saat ini, ini akan sangat menyakitkan. Kode tes disadap tidak terdengar seperti situasi optimal, sekarang bukan?
marktani
ya, saya mengambil stasiun dari Knuth :)
Yusubov
9
Anda mengulangi diri Anda sendiri: Anda mengulangi diri Anda dengan mengatakan "Pengulangan adalah akar dari semua kejahatan" dalam judul dan kalimat intro Anda.
Thomas Eding
Ya, saya melakukan itu dengan sengaja untuk menekankan pentingnya dan Anda dipersilakan untuk mengedit bagian itu :)
Yusubov
1
Thomas Eding, Anda mengulangi diri Anda juga. Anda mengulangi diri Anda juga =)
marktani
7

Masih cukup buruk untuk memotong dan menempel. Ada beberapa masalah.

Tes Anda mungkin rapuh, karena Anda rentan terhadap sesuatu yang memerlukan perubahan pada semua kode yang disalin dan ditempelkan itu. Apakah Anda harus menulis ulang semua tes?

Jika Anda tidak dapat merangkum logika menjadi metode pembantu di luar tes Anda, Anda tidak dapat menulis tes metode pembantu itu sendiri. Menulis tes metode uji biasanya sulit untuk membuat berharga, karena Anda harus memecahkan kode Anda untuk menguji tes. Tetapi Anda dapat menguji metode metode pembantu.

Mungkin membuat tes kurang mudah dibaca. Blok besar kode yang disalin mungkin lebih sulit dibaca daripada metode panggilan untuk membantu dengan nama deskriptif.

Semua yang saya daftarkan adalah sesuatu yang mungkin menjadi masalah. Jika Anda menemukan tidak satupun dari mereka yang benar - benar masalah maka tentu saja tidak masalah.

psr
sumber
> metode ajakan untuk membantu dengan nama deskriptif. Bukan masalah dengan ini yang unit test Anda sekarang menjadi program sendiri - yang mana harus dihindari. Bagaimana jika beberapa tes gagal - apakah kode yang rusak, atau pembantu tes?
dwjohnston
4

Saya dulu setuju dengan Anda. Tapi kemudian, seiring waktu, saya menemukan bahwa setiap perubahan yang saya buat (khususnya perubahan DI dalam unit test) memerlukan banyak tes untuk berubah dan itu rumit. Sekarang saya berlangganan ke sekolah KERING, bahkan ketika menulis tes.

Untuk pengujian GUI, Anda mungkin ingin melihat pola PageObject untuk mengurangi kode berulang.

pdr
sumber
2

Saya akan merekomendasikan mengambil pola XUnit. Saya dulu memiliki masalah yang sama persis sampai saya mulai memanfaatkan buku itu. Pola Obyek Ibu terdengar seperti itu akan menjadi yang paling bermanfaat untuk skenario Anda.

Seperti orang lain yang disebutkan, enkapsulasi kode pengaturan ini mungkin sulit, tetapi harus mengubahnya di semua tempat yang Anda salin dan tempelkan lebih dari itu.

Michael Brown
sumber
+1 untuk Object Mother patternkode inisialisasi umum.
k3b
2

Haruskah orang mencoba dan membatasi repitisi ketika mereka bisa - ya. Tetapi hasilnya tergantung pada situasinya. Ini bisa kembali ke perdebatan 'praktik terbaik'. Tetapi pertanyaannya adalah apa yang terbaik untuk Anda dalam situasi ini. Ada pengecualian untuk setiap aturan.

Beberapa hal yang akan saya tanyakan adalah: 1) Seberapa besar kemungkinan fungsi ini sedang diuji dalam UAT akan berubah? Jika tidak mungkin itu akan berubah, maka ada sedikit kesempatan bahwa Anda harus memperbarui setiap set kode Anda. 2) Jika ada perubahan dalam UAT, apakah akan selalu berdampak pada setiap set kode yang disalin atau mungkin hanya berdampak pada satu atau dua set? Jika mungkin terisolasi dan hanya memerlukan perubahan ke satu set, mungkin membantu untuk memisahkannya. 3) Seberapa komplekskah metode awal jika Anda mencoba dan membuatnya menangani semua skenario? Apakah Anda menambahkan banyak bersarang jika / else / loop? Jika Anda mulai melakukan semua percabangan secara berlebihan, Anda mungkin berakhir dengan kode yang sulit dipahami. Apakah akan lebih mudah untuk membuat pembaruan di setiap teks yang disalin daripada mengunjungi kembali semua logika percabangan?

Jika Anda mandek copy / paste / alter saya akan berpikir Anda ingin menambahkan komentar seperti 'Ini disalin dalam metode xyz'. Dengan begitu Anda akan diingatkan untuk memperbarui semua versi kode yang disisipkan. Atau (berasal dari pengguna SilkTest lainnya) dapatkah Anda menambahkan file inc terpisah yang akan fokus hanya pada kode yang diulang ini. Dengan begitu Anda memiliki semua variasi di satu tempat dan dapat dengan mudah melihat berbagai metode yang memerlukan pembaruan.

Dan B
sumber
0

Satu Prosedur Besar

Satu pemikiran: Kedengarannya Anda mencoba menghindari kode cut-n-paste dengan membuat metode seperti:

testScreen(title, fieldList, linkList, param1, param2, param3,...) {
    test that the layout at the top of the screen is correct
    test if PageTitle == title?
    for each field in fieldList:
        check that it appears in order on the screen
    for each field in linkList:
        check that it appears in order on the screen
    test if param1 is whatever...
    test if param2 is whatever...
    etc.
    test that the bottom of the screen is correct
}

Banyak Prosedur Kecil (toolkit)

Apakah Anda juga mempertimbangkan pendekatan yang berlawanan? Alih-alih mengirimkan sejuta parameter ke satu prosedur testScreen () besar, mungkin buat kerangka kerja Anda sendiri atau tool-kit dari prosedur pembantu kecil yang Anda keluarkan saat Anda membutuhkannya. Suka:

testScreenTop()
verifyLinks(list)
testScreenBottom()

Anda masih memotong dan menempelkan prosedur ini ke setiap layar, tetapi Anda memotong dan menempelkan potongan kode yang lebih kecil dan mengukir potongan kesamaan yang tidak dipotong dan disisipkan (isi dari masing-masing prosedur kecil).

Potong dan tempel

Satu-satunya kode cut-and-paste belum menggigit saya adalah ketika kode itu dibuang sebelum saya harus mengubahnya. Kekhawatiran terbesar saya dengan tes UI adalah seberapa cepat mereka menjadi usang. Jika Anda menemukan Anda membuang semua kode sebelum mengubahnya, maka mungkin Anda telah menemukan ceruk tempat memotong dan menempel tidak apa-apa! Juga, itu tidak begitu buruk ketika tidak ada kode hilir dari kode cut-and-paste (misalnya di UI aplikasi). Jika Anda menyisipkan lebih dari 3 baris, saya benar-benar ingin melakukan sesuatu tentang itu. Setidaknya ambil langkah untuk menguranginya!

Pengujian UI Otomatis

Heck, jika Anda dapat membuktikan produktivitas yang lebih besar dengan pengujian UI otomatis daripada pengujian manual menggunakan teknik apa pun (biaya penulisan / pemeliharaan tes otomatis lebih rendah daripada pengujian secara manual setiap kali, namun kualitasnya sama) Saya pikir Anda harus menulis makalah. Saya akan membacanya! Saya dapat melihat judulnya sekarang, "Potong-dan-tempel Kode, Menangkan Net untuk Pengujian UI!"

GlenPeterson
sumber
0

Ini tidak terlalu buruk. Bahkan, jika Anda menemukan pola kode tertentu sedang digunakan sangat sering dan perubahannya sangat rutin (seperti beberapa string, atau nilai parameter), Anda bahkan dapat menulis generator kode yang menghasilkan kode uji berulang berdasarkan kecil (- ish?) masukkan daftar nilai yang berubah. Saya sudah melakukan ini (menghasilkan kode uji) berkali-kali, menggunakan file batch, skrip SQLPlus, bahkan makro Excel (kedengarannya jelek, tetapi variabel untuk skrip tes yang berbeda sudah ada dalam spreadsheet) dan ini bisa menjadi penghemat waktu yang tepat. . Masalahnya adalah jika ada perubahan dalam struktur keseluruhan dari kode kasus pengujian berulang, Anda hanya dapat membuat ulang apa pun yang Anda butuhkan.

FrustratedWithFormsDesigner
sumber
0

Ini sama dengan sebagian besar jawaban lain tetapi dengan cara yang bisa dipahami oleh manajer non teknis.

Bayangkan skenario kesalahan berikut:

  • Seseorang membuat perubahan pada basis data di mana banyak dari tes Anda bergantung.
  • Konsekuensi: tiba-tiba 117 dari 2933 tes otomatis Anda gagal.

Apa yang akan kamu lakukan?

  • (1) memperbaiki 117 tes?
  • (2) hapus 117 tes dan implementasikan kembali melalui salin & tempel baru. ini mungkin lebih mudah daripada (1)
  • (3) refactor tes untuk mengekstrak kode umum sehingga di masa depan Anda harus menyesuaikan hanya satu metode (atau beberapa) untuk memperbaiki tes (lihat jawaban @ pdr atau @ Michael Brown)
  • (4) hapus 117 tes tanpa menerapkan kembali tes

Dari pengalaman saya:

Ketika memperkenalkan tes manajemen otomatis suka "salin & tempel-tes": Anda mendapatkan banyak tes dalam waktu singkat.

Setelah beberapa "skenario kesalahan" manajemen lebih suka (4) karena memperbaiki "salin & tempel-tes" sangat mahal.

Lakukan dengan benar di tempat pertama (3) tidak akan begitu cepat tetapi meningkatkan kemungkinan bahwa tes akan bertahan

k3b
sumber