Haruskah ada unit test untuk ekspresi reguler yang kompleks?

34

Haruskah saya menulis unit test untuk ekspresi reguler yang kompleks dalam aplikasi saya?

  • Di satu sisi: mereka mudah untuk diuji karena format input dan output seringkali sederhana dan terdefinisi dengan baik, dan mereka sering menjadi sangat kompleks sehingga pengujian mereka secara khusus bernilai.
  • Di sisi lain: mereka sendiri jarang menjadi bagian dari antarmuka beberapa unit. Mungkin lebih baik hanya menguji antarmuka dan melakukannya dengan cara yang secara implisit menguji regex.

EDIT:

Saya setuju dengan Doc Brown yang dalam komentarnya mencatat bahwa ini adalah kasus khusus pengujian unit komponen internal .

Tetapi sebagai komponen internal, regex memiliki beberapa karakteristik khusus:

  1. Regex baris tunggal bisa sangat kompleks tanpa benar-benar menjadi modul terpisah.
  2. Regex input peta ke output tanpa efek samping dan karenanya sangat mudah untuk diuji secara terpisah.
Lii
sumber
12
"Mereka sendiri jarang menjadi bagian dari antarmuka beberapa unit." - jika kelas Anda memiliki kode menarik yang terkubur jauh di bawah antarmuka, pisahkan kelas Anda. Ini adalah contoh bagaimana berpikir tentang tess dapat meningkatkan desain.
Nathan Cooper
3
Pertanyaan yang sama dengan cara yang lebih umum: komponen internal mana yang harus diuji unit? Lihat programmers.stackexchange.com/questions/16732/…
Doc Brown
Agak terkait, lihat Regex101. Mereka memiliki bagian untuk menulis unit test untuk regex Anda. Sebagai contoh: regex101.com/r/tR3mJ2/2
David mengatakan Reinstate Monica
3
Penafian - komentar ini adalah pendapat saya yang rendah hati: 1 pertama-tama saya percaya bahwa regexps kompleks adalah murni jahat - juga lihat blog.codinghorror.com/... 2 nilai sebenarnya dari pengujian ekspresi seperti itu muncul ketika Anda mengujinya di database besar nyata data blog.codinghorror.com/testing-with-the-force 3 Saya punya perasaan aneh bahwa tes ini bukan tes unit persis
Boris Treukhov

Jawaban:

101

Mengesampingkan dogmatisme, pertanyaan sebenarnya adalah apakah itu memberikan nilai pada unit test ekspresi reguler yang kompleks. Tampaknya cukup jelas bahwa ia memberikan nilai (terlepas dari apakah regex merupakan bagian dari antarmuka publik) jika regex cukup kompleks, karena memungkinkan Anda untuk menemukan dan mereproduksi bug dan mencegah dari regresi.

JacquesB
sumber
25
1, meskipun jika ekspresi reguler cukup kompleks bahwa ini adalah masalah, maka itu mungkin masuk akal untuk memindahkannya ke dalam sebuah unit "wrapper" dengan metode yang tepat ( isValid, parse, tryParse, atau entah apa lagi, tergantung persis bagaimana itu digunakan), sehingga bahwa kode klien tidak harus tahu bahwa itu saat ini diterapkan menggunakan regex. Unit pembungkus kemudian akan memiliki tes terperinci, yang - sekali lagi - tidak perlu mengetahui implementasi saat ini. Tes-tes ini, tentu saja, secara de facto menguji regex, tetapi dengan cara implementasi-agnostik.
ruakh
1
Reg ex adalah program, meskipun dalam bahasa yang terspesialisasi dan sangat singkat. Dengan demikian, pengujian sesuai untuk ekspresi nontrivial ... Dan tentu saja kode yang memanggil ekspresi harus diuji, yang mungkin secara implisit menguji yang dipesan.
keshlam
6
@ruakh Well berkata. Manfaat bagi kelas wrapper untuk regex adalah Anda bisa menggantinya dengan kode biasa jika perlu. Kode dengan input / output yang kompleks harus selalu memiliki unit testing, karena sangat sulit untuk debug tanpa. Jika Anda perlu merujuk ke dokumentasi untuk memahami efek kode, itu harus memiliki unit test. Jika itu hanya pemetaan 1: 1 cepat seperti konversi tipe, maka tidak ada masalah. Regex bisa melewati titik itu dengan membutuhkan dokumen dengan sangat cepat.
Aaron3468
4
@ Lii: Regex tidak pantas mendapatkan perlakuan khusus. Regex adalah unit dalam kasus ini, jadi kami mengujinya.
JacquesB
1
@ruakh saya baru akan menulis jawaban untuk efek itu. Saya setuju bahwa menggunakan regex adalah detail implementasi. Yang penting adalah bahwa hal-hal valid ketika mereka seharusnya, dan gagal untuk memvalidasi ketika mereka seharusnya. Uji FooValidatorinput dan outputnya, maka Anda tidak perlu khawatir tentang bagaimana hal itu dilakukan. ++
RubberDuck
21

Regex bisa menjadi alat yang ampuh, tetapi itu bukan alat yang bisa Anda percayai untuk tetap berfungsi jika Anda membuat perubahan kecil pada regex yang kompleks.

Jadi buat banyak tes yang mendokumentasikan kasus-kasus yang harus diliput. Dan membuat banyak tes yang mendokumentasikan kasus itu harus gagal, jika digunakan untuk validasi.

Setiap kali Anda perlu mengubah regex Anda, Anda menambahkan case baru sebagai tes, memodifikasi regex Anda dan berharap yang terbaik.

Jika saya berada di organisasi yang secara umum tidak menggunakan tes unit, saya masih akan menulis program uji yang akan menguji setiap regex yang kami gunakan. Saya bahkan akan melakukannya pada waktu saya sendiri jika harus, rambut saya tidak perlu kehilangan warna lagi.

Bengkok
sumber
3

Ekspresi reguler adalah kode bersama dengan sisa aplikasi Anda. Anda harus menguji bahwa keseluruhan kode melakukan apa yang Anda harapkan. Ini memiliki beberapa tujuan:

  • Tes adalah dokumentasi yang dapat dijalankan. Ini menunjukkan dengan jelas apa yang perlu Anda lakukan kode. Jika diuji, itu penting.
  • Pemelihara masa depan dapat yakin bahwa jika mereka memodifikasinya, pengujian akan memastikan bahwa perilaku tidak berubah.

Karena ada rintangan ekstra untuk diatasi dengan memiliki kode dalam bahasa yang berbeda tertanam dengan yang lain, Anda kemungkinan besar harus memberikan perhatian ekstra ini untuk kepentingan pemeliharaan.

Thorbjørn Ravn Andersen
sumber
1

Singkatnya, Anda harus menguji aplikasi Anda, titik. Apakah Anda menguji regex Anda dengan tes otomatis yang menjalankannya secara terpisah, sebagai bagian dari kotak hitam yang lebih besar atau jika Anda hanya mengotak-atiknya dengan tangan adalah hal kedua yang perlu Anda pastikan agar berfungsi.

Keuntungan utama dari unit test adalah mereka dapat menghemat waktu. Mereka membiarkan Anda menguji benda sebanyak yang Anda suka sekarang atau di titik mana pun di masa depan. Jika ada alasan untuk percaya bahwa regex Anda pada titik mana saja akan di-refactored, di-tweak, mendapatkan lebih banyak kendala dll, maka ya, Anda mungkin ingin beberapa tes regresi untuk itu, atau ketika Anda mengubahnya, Anda harus pergi melalui satu jam memikirkan semua kasus tepi sehingga Anda tidak memecahkannya. Itu, atau Anda belajar hidup dengan takut akan kode Anda dan tidak pernah mengubahnya.

sara
sumber
3
Aturan praktis yang saya sadari; jika saya membutuhkan dokumen untuk menulis dan memeriksa kode, maka saya akan memerlukan unit test. Mereka telah menyelamatkan saya banyak sakit kepala, menangkap pointer nol, tidak ada tipe, dan output yang salah. Mereka juga memberikan pengguna akhir kemampuan untuk memperbaiki kode Anda untuk spec dengan upaya minimal ketika itu pasti rusak.
Aaron3468
-1

Di sisi lain: mereka sendiri jarang menjadi bagian dari antarmuka beberapa unit. Mungkin lebih baik hanya menguji antarmuka dan melakukannya dengan cara yang secara implisit menguji regex.

Saya pikir dengan ini Anda menjawab sendiri. Regex dalam suatu unit kemungkinan besar merupakan detail implementasi.

Apa yang berlaku untuk pengujian SQL Anda mungkin juga berlaku untuk regex. Ketika Anda mengubah sepotong SQL, Anda mungkin menjalankannya melalui beberapa klien SQL dengan tangan untuk melihat apakah itu menghasilkan apa yang Anda harapkan. Hal yang sama berlaku ketika saya mengubah regex saya menggunakan beberapa alat regex dengan beberapa input sampel untuk melihat apakah ia melakukan apa yang saya harapkan.

Apa yang saya temukan berguna adalah komentar di dekat regex dengan sampel teks yang harus cocok.

Christiaan
sumber
" Ketika Anda mengubah sepotong SQL, Anda mungkin menjalankannya melalui beberapa klien SQL dengan tangan untuk melihat apakah itu menghasilkan apa yang Anda harapkan. " Tapi ini menjawab pertanyaan dengan cara lain ... Jika saya perlu atau berpikir itu berguna menguji regex dengan tangan maka saya harus membuat unit test untuk itu. Tepat inilah yang membuatnya sulit untuk diputuskan!
Lii
Itu sangat tergantung. Yang Anda inginkan dari unit Anda adalah kemampuan untuk membuat perubahan. Seberapa sering Anda mengubah regex tertentu? Jika jawabannya sering maka dengan segala cara membuat tes untuk itu.
Christiaan
8
Semua hal lain dianggap sama, lebih baik memiliki tes otomatis daripada "tes dengan tangan."
Robert Harvey
1
Mengapa Anda tidak menguji regex menggunakan otomatisasi?
Tony Ennis
1
Itu adalah bagian dari metode dan yang ingin saya katakan adalah bahwa tidak perlu secara khusus menguji regex jika Anda sudah menguji metode itu. Tetapi jika Anda melakukannya, Anda mungkin lebih baik mengekstraksi regex menjadi fungsi terpisah yang Anda uji secara terpisah.
Christiaan
-5

Jika Anda harus bertanya, jawabannya adalah ya.

Misalkan beberapa FNG datang dan berpikir dia dapat "meningkatkan" regex Anda. Sekarang, dia seorang FNG, jadi otomatis itu idiot. Persis seperti orang yang tidak boleh menyentuh kode berharga Anda dalam keadaan apa pun, pernah! Tapi mungkin dia punya hubungan keluarga dengan PHB atau semacamnya, jadi tidak ada yang bisa Anda lakukan.

Kecuali Anda tahu PHB akan menyeret Anda menendang dan berteriak kembali ke proyek ini untuk "mungkin memberi orang itu beberapa petunjuk tentang bagaimana Anda membuat kekacauan ini" ketika semuanya memburuk. Jadi, Anda menuliskan semua kasus yang telah Anda pertimbangkan dengan hati - hati ketika membangun karya agung Anda yang indah untuk berekspresi.

Dan karena Anda telah menuliskan semuanya, Anda dua pertiga dari cara memiliki satu set kasus uji, karena - mari kita hadapi itu - kasus uji regex mati mudah dijalankan setelah kerangka kerja dibangun.

Jadi sekarang, Anda memiliki serangkaian kondisi tepi, alternatif, dan hasil yang diharapkan. Dan tiba - tiba kasus uji adalah dokumentasi seperti yang dijanjikan dalam semua posting blog saya Agile. Anda hanya menunjukkan kepada FNG bahwa jika "perbaikannya" tidak lulus uji kasus yang ada, itu tidak banyak perbaikan, bukan? Dan di mana diusulkannya kasus uji baru yang menunjukkan beberapa masalah dengan kode asli, yang sejak berhasil ia tidak perlu memodifikasi lagi !!!

Austin Hastings
sumber
3
apa itu FNG? Ini sepertinya bukan jawaban yang buruk bagi saya, tetapi definisi yang hilang untuk FNG (googlin untuk itu hanya memberikan hasil yang tidak terkait, jadi mungkin jawaban ini hanya diturunkan karena FNG?)
GameDeveloper
1
Saya menduga bahwa Google membawa Anda ke tempat yang tepat. ;-) ( en.wikipedia.org/wiki/FNG_syndrome )
Austin Hastings
Kecuali Anda seorang jenius pemrograman absolut, akan ada programmer yang lebih berpengalaman mempertimbangkan apa yang Anda lakukan seperti Anda melihat orang baru. Anda mungkin ingin mempertimbangkan untuk lebih rendah hati.
Thorbjørn Ravn Andersen