Bagaimana cara membuat satu tes tergantung pada hasil tes lain?


13

Katakanlah ada kelas utilitas yang menyediakan beberapa metode statis umum yang digunakan di mana-mana dalam kode Anda oleh banyak kelas lainnya.

Bagaimana Anda merancang tes unit Anda untuk konsumen utilitas sehingga tes mereka gagal jika salah satu tes utilitas tidak lulus? Bisakah Anda melakukannya atau Anda harus memeriksanya sendiri apakah tes kelas utilitas semuanya hijau?

Sebagai contoh saya memiliki utilitas pembagi-pesan yang digunakan (atau lebih tepatnya keluarannya) oleh pengurai pesan. Saya ingin memastikan bahwa splitter-pesan berfungsi dengan benar sebelum parser-pesan diuji.

Saya telah menulis tes untuk keduanya tetapi apakah ada cara untuk menghubungkan mereka dan membuat satu tes tergantung pada hasil beberapa tes lainnya?

Saya tidak dapat menemukan tag yang cocok untuk ini, tetapi saya menggunakan mesin uji unit Visual Studio.


1
Saya mengerti bahwa parser tidak berfungsi dengan benar jika utilitas gagal. Tetapi jika Anda menjalankan tes Anda, Anda akan melihat bahwa tes utilitas gagal. Mengapa Anda ingin tes lain gagal juga?
Eugen Martynov

1
Saya belum pernah mendengar ada yang menginginkan ini sebelumnya. Apa yang ingin kamu capai?
Esben Skov Pedersen


Saya menggunakan beberapa fungsi utilitas untuk menyiapkan data untuk pengujian parser jadi saya ingin benar-benar memastikan utilitas berfungsi dengan benar sebelum saya menguji apa pun.
t3chb0t

3
@ t3chb0t Jika Anda ingin memastikan utilitas Anda berfungsi, maka Anda perlu menulis unit test untuk memverifikasi utilitas Anda. Tes unit harus berupa atom. Anda hanya ingin mereka menguji satu komponen.
maple_shaft

Jawaban:


11

Tidak ada gunanya memastikan bahwa setiap cacat pada sistem Anda benar-benar melakukan satu tes.

Sebuah test suite memiliki satu pekerjaan: memverifikasi bahwa tidak ada cacat yang diketahui. Jika ada cacat, tidak masalah jika satu tes gagal atau 10. Jika Anda terbiasa dengan gagal test suite Anda, jika Anda mencoba untuk mengukur seberapa "buruk" program Anda dengan menghitung tes gagal, Anda tidak menggunakan pengujian regresi dengan cara yang benar. Paket tes harus lulus semua tes sebelum Anda mempublikasikan kode.

Satu-satunya alasan yang valid untuk melewatkan tes adalah jika mereka menguji fungsionalitas yang tidak lengkap dan mengambil jumlah waktu yang banyak yang bisa Anda manfaatkan dengan lebih baik saat menerapkan hal yang seharusnya mereka uji. (Bagaimanapun, itu hanya masalah jika Anda tidak mempraktikkan pengembangan yang digerakkan oleh pengujian ketat, tetapi itu adalah pilihan yang valid.)

Kalau tidak, jangan repot-repot mencoba membuat test suite Anda menjadi indikator yang memberitahu Anda apa yang salah. Itu tidak akan pernah tepat, dan tidak seharusnya demikian. Seharusnya melindungi Anda dari melakukan kesalahan yang sama dua kali, itu saja.


8

Tergantung pada alat Anda, tetapi Anda mungkin tidak bisa (dan tidak seharusnya)

Beberapa kerangka kerja pengujian Unit ( misalnya PHPUnit ) memungkinkan Anda melakukan 'rantai' pengujian sehingga tes gagal pada satu level tidak menjalankan tes lain. Namun, saya ragu ini akan memperbaiki masalah Anda untuk situasi ini.

Tidak memungkinkan eksekusi yang dieksekusi agar tes dapat diisolasi satu sama lain dan umumnya dianggap sebagai hal yang baik. Bayangkan apa yang akan terjadi jika tes tidak hanya berjalan sendiri tetapi juga menyediakan data untuk tes lain untuk dikerjakan ...

Anda dapat menempatkan metode utilitas ini dalam solusi atau kategori uji terpisah. Pastikan mereka secara visual 'menonjol' di pelari tes Anda, atau bahwa kategori ini berjalan lebih dulu dan tidak menjalankan tes lain jika tes dalam kategori ini gagal *. Ketika salah satu dari tes ini gagal, kegagalan mungkin akan mengalir di semua tes dan Anda harus membantu memastikan bahwa siapa pun yang menjalankan tes tahu untuk memulai dengan memperbaiki tes yang gagal ini terlebih dahulu. Hal yang sama berlaku untuk Tes Unit dan Tes Integrasi. Jika Unittest gagal, itu akan mengalir dan menyebabkan segala macam kekacauan dalam tes Integrasi. Semua orang tahu bahwa ketika tes Unit DAN Integrasi gagal, Anda mulai dengan memeriksa Unittests ...

* Dengan skrip pembuatan atau pengujian otomatis Anda dapat menjalankan kategori ini terlebih dahulu, periksa hasilnya dan hanya jalankan tes lain jika batch pengujian pertama ini lulus.


5

Coba pertahankan atom uji unit Anda. Ingat bahwa kode pengujian otomatis juga merupakan bagian dari basis kode Anda, tetapi kode itu sendiri tidak sedang diuji, jadi jaga sesederhana dan sejelas mungkin.

Untuk menjawab pertanyaan Anda secara lebih langsung, tidak ada jaminan urutan pelaksanaan tes sehingga tidak ada cara untuk menjamin bahwa tes utilitas Anda berhasil sebelum tes lain dijalankan. Jadi tidak ada cara yang dijamin untuk mencapai apa yang Anda inginkan sambil masih memiliki satu test suite untuk semua tes Anda.

Anda dapat memindahkan utilitas ke solusi mereka sendiri dan menambahkan referensi ke dll yang dihasilkan dalam proyek Anda saat ini.


4

Dalam ringkasan, Anda tidak ingin menggunakan alat / teknik untuk melakukan hal-hal selain apa yang dimaksudkan untuk itu.

Apa yang Anda coba lakukan terdengar seperti masalah yang bisa diselesaikan dengan mudah dengan praktik CI (integrasi berkelanjutan).

Dengan cara ini Anda dapat menyimpan tes atom Anda seperti yang disarankan dan biarkan CI mengurus verifikasi tes Anda.

Jika ada tes yang gagal Anda dapat mengaturnya sehingga tidak membiarkan kode Anda dipublikasikan.


4

Saya memiliki kebiasaan untuk selalu mencoba membedakan kode tingkat aplikasi dari kode tingkat kerangka kerja, jadi saya telah menemui masalah yang sering Anda jelaskan: Anda biasanya ingin semua kode tingkat kerangka kerja diuji sebelum kode tingkat aplikasi mana pun mulai diuji. . Juga, bahkan dalam kode tingkat kerangka kerja, cenderung ada beberapa modul kerangka dasar yang digunakan oleh semua modul kerangka kerja lainnya, dan jika ada sesuatu yang gagal dalam fundamental, tidak ada gunanya menguji hal lain.

Sayangnya, pemasok kerangka pengujian cenderung memiliki ide-ide yang agak kaku tentang bagaimana kreasi mereka dimaksudkan untuk digunakan, dan agak protektif terhadap ide-ide itu, sementara orang-orang yang menggunakan kerangka kerja mereka cenderung menerima penggunaan yang dimaksud tanpa mempertanyakan. Ini bermasalah, karena menghambat eksperimen dan inovasi. Saya tidak tahu tentang orang lain, tetapi saya lebih suka memiliki kebebasan untuk mencoba melakukan sesuatu dengan cara yang aneh, dan melihat sendiri apakah hasilnya lebih baik atau lebih buruk daripada cara yang ditetapkan, daripada tidak memiliki kebebasan untuk melakukan hal-hal dengan cara saya di tempat pertama.

Jadi, menurut saya, dependensi tes akan menjadi hal yang luar biasa, dan sebagai pengganti, kemampuan untuk menentukan urutan tes yang akan dieksekusi akan menjadi hal terbaik berikutnya.

Satu-satunya cara yang saya temukan untuk mengatasi masalah pemesanan tes adalah dengan penamaan hati-hati, sehingga dapat mengeksploitasi kecenderungan kerangka pengujian untuk menjalankan tes dalam urutan abjad.

Saya tidak tahu bagaimana ini bekerja di Visual Studio, karena saya belum melakukan apa pun yang melibatkan pengujian ekstensif dengan C #, tetapi di sisi Jawa dunia ini berfungsi sebagai berikut: Di bawah folder sumber proyek kami biasanya memiliki dua subfolder, satu disebut "utama", berisi kode produksi, dan satu disebut "tes", yang berisi kode pengujian. Di bawah "main" kami memiliki hierarki folder yang persis sesuai dengan hierarki paket dari kode sumber kami. Paket Java kira-kira sesuai dengan ruang nama C #. C # tidak mengharuskan Anda untuk mencocokkan hierarki folder dengan hirarki namespace, tetapi disarankan untuk melakukannya.

Sekarang, apa yang biasanya dilakukan orang di dunia Java adalah bahwa di bawah folder "test" mereka mencerminkan hierarki folder yang ditemukan di bawah folder "utama", sehingga setiap tes berada dalam paket yang sama persis dengan kelas yang diuji. Alasan di balik ini adalah bahwa cukup sering kelas pengujian perlu mengakses anggota-paket pribadi kelas yang diuji, sehingga kelas pengujian harus dalam paket yang sama dengan kelas yang diuji. Di sisi C # dunia tidak ada yang namanya visibilitas namespace-lokal, jadi tidak ada alasan untuk mencerminkan hierarki folder, tapi saya pikir programmer C # kurang lebih mengikuti disiplin yang sama dalam menyusun struktur folder mereka.

Dalam kasus apa pun, saya menemukan seluruh gagasan ini untuk memungkinkan kelas pengujian memiliki akses ke anggota kelas-paket yang sedang diuji salah arah, karena saya cenderung menguji antarmuka, bukan implementasi. Jadi, hierarki folder pengujian saya tidak harus mencerminkan hierarki folder dari kode produksi saya.

Jadi, yang saya lakukan adalah memberi nama folder (artinya, paket) dari pengujian saya sebagai berikut:

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

Ini menjamin bahwa semua tes untuk "SomeSubsystem" akan dieksekusi sebelum semua tes untuk "SomeOtherSubsystem", yang pada gilirannya semua akan dieksekusi sebelum semua tes untuk "AndYetAnotherSubsystem", dan seterusnya, dan sebagainya.

Di dalam folder, file uji individual diberi nama sebagai berikut:

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

Tentu saja, ini sangat membantu bahwa IDE modern memiliki kemampuan refactoring yang kuat yang memungkinkan Anda untuk mengubah nama seluruh paket (dan semua sub-paket, dan semua kode yang mereferensikannya) hanya dengan beberapa klik dan penekanan tombol.


2
I don't know about everyone else, but I would prefer to have the freedom to try to do something in an odd way, and see for myself whether the results are better or worse++ sobat. Saya tidak tahu bahwa saya menyukai solusinya, tetapi saya menyukai sikap yang Anda perlihatkan di sana.
RubberDuck
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.