Saya bekerja dengan sistem berikut:
Network Data Feed -> Third Party Nio Library -> My Objects via adapter pattern
Kami baru-baru ini memiliki masalah di mana saya memperbarui versi perpustakaan yang saya gunakan, yang, antara lain, menyebabkan cap waktu (yang dikembalikan oleh perpustakaan pihak ketiga long
), diubah dari milidetik setelah zaman ke zaman nanodetik setelah zaman.
Masalah:
Jika saya menulis tes yang mengejek objek perpustakaan pihak ketiga, tes saya akan salah jika saya telah membuat kesalahan tentang objek perpustakaan pihak ketiga. Sebagai contoh, saya tidak menyadari bahwa stempel waktu berubah presisi, yang mengakibatkan perlunya perubahan dalam tes unit, karena tiruan saya mengembalikan data yang salah. Ini bukan bug di perpustakaan , itu terjadi karena saya melewatkan sesuatu di dokumentasi.
Masalahnya adalah, saya tidak bisa yakin tentang data yang terkandung dalam struktur data ini karena saya tidak bisa menghasilkan yang nyata tanpa umpan data nyata. Objek-objek ini besar dan rumit dan memiliki banyak potongan data yang berbeda di dalamnya. Dokumentasi untuk perpustakaan pihak ketiga buruk.
Pertanyaan:
Bagaimana saya bisa mengatur tes saya untuk menguji perilaku ini? Saya tidak yakin dapat menyelesaikan masalah ini dalam unit test, karena tes itu sendiri dapat dengan mudah salah. Selain itu, sistem terintegrasinya besar dan rumit dan mudah untuk melewatkan sesuatu. Misalnya, dalam situasi di atas, saya telah menyesuaikan penanganan stempel waktu dengan benar di beberapa tempat, tetapi saya melewatkan satu di antaranya. Sistem tampaknya melakukan sebagian besar hal yang benar dalam pengujian integrasi saya, tetapi ketika saya menggunakannya untuk produksi (yang memiliki lebih banyak data), masalahnya menjadi jelas.
Saya tidak memiliki proses untuk tes integrasi saya sekarang. Pengujian pada dasarnya adalah: cobalah untuk menjaga unit tes tetap bagus, tambahkan lebih banyak tes saat ada masalah, kemudian gunakan ke server pengujian saya dan pastikan semuanya tampak waras, kemudian gunakan untuk produksi. Masalah stempel waktu ini lulus uji unit karena tiruan dibuat salah, lalu lulus uji integrasi karena tidak menyebabkan masalah langsung yang jelas. Saya tidak punya departemen QA.
Timestamp
kelas (mengandung representasi yang mereka inginkan) dan menyediakan metode bernama (.seconds()
,.milliseconds()
,.microseconds()
,.nanoseconds()
) dan tentu saja bernama konstruktor. Maka tidak akan ada masalah.Jawaban:
Sepertinya Anda sudah melakukan uji tuntas. Tapi ...
Pada tingkat yang paling praktis, selalu sertakan beberapa tes integrasi "loop penuh" yang baik dalam kode Anda untuk kode Anda sendiri, dan tulis lebih banyak pernyataan daripada yang Anda pikir Anda butuhkan. Khususnya, Anda harus memiliki beberapa tes yang melakukan siklus validasi create-read- [do_stuff] penuh.
Dan sepertinya Anda sudah melakukan hal semacam ini. Anda hanya berurusan dengan perpustakaan yang rapuh dan / atau rumit. Dan dalam hal ini, ada baiknya untuk melakukan beberapa jenis tes "ini adalah cara perpustakaan bekerja" yang keduanya memverifikasi pemahaman Anda tentang perpustakaan dan berfungsi sebagai contoh cara menggunakan perpustakaan.
Misalkan Anda perlu memahami dan bergantung pada bagaimana parser JSON menginterpretasikan setiap "tipe" dalam string JSON. Sangat membantu dan sepele untuk memasukkan sesuatu seperti ini di suite Anda:
Tetapi kedua, ingat bahwa pengujian otomatis dalam bentuk apa pun, dan pada hampir semua tingkat kekakuan, masih akan gagal melindungi Anda dari semua bug. Sangat umum untuk menambahkan tes saat Anda menemukan masalah. Tidak memiliki departemen QA, ini berarti banyak masalah yang akan ditemukan oleh pengguna akhir.
Dan pada tingkat yang signifikan, itu wajar saja.
Dan ketiga, ketika pustaka mengubah arti nilai-kembali atau bidang tanpa mengganti nama bidang atau metode atau sebaliknya "melanggar" kode dependen (mungkin dengan mengubah tipenya), saya akan sangat tidak senang dengan penerbit itu. Dan saya berpendapat bahwa, meskipun Anda mungkin harus membaca changelog jika ada, Anda mungkin juga harus menyerahkan sebagian stres Anda kepada penerbit. Saya berpendapat mereka membutuhkan kritik yang diharapkan-konstruktif ...
sumber
(new JSONParser()).parse(datastream)
, karena mereka mengambil data langsung dari aNetworkInterface
dan semua kelas yang melakukan parsing sebenarnya adalah paket pribadi dan proguarded.NetworkInterface
... apakah ini sesuatu yang Anda dapat memasukkan data ke dengan menghubungkan antarmuka ke port di localhost atau sesuatu?NetworkInterface
. Ini adalah objek tingkat rendah untuk langsung bekerja dengan kartu jaringan dan membuka soket di atasnya, dll.Jawaban singkat: Sulit. Anda mungkin merasa tidak ada jawaban yang baik, dan itu karena tidak ada jawaban yang mudah.
Jawaban panjang: Seperti yang dikatakan @ptyx , Anda memerlukan tes sistem dan tes integrasi serta tes unit:
Beberapa saran spesifik:
Saya telah melihat pemrograman yang digambarkan sebagai aktivitas belajar tentang masalah dan ruang solusi. Mendapatkan segala sesuatunya sebelum waktunya mungkin tidak layak, tetapi Anda bisa belajar setelah itu. ("Saya memperbaiki penanganan stempel waktu di beberapa tempat tetapi terlewatkan satu. Dapatkah saya mengubah tipe data atau kelas saya untuk membuat penanganan stempel waktu lebih eksplisit dan lebih sulit untuk dilewatkan, atau membuatnya lebih tersentralisasi sehingga saya hanya memiliki satu tempat untuk berubah? Dapatkah saya memodifikasi pengujian saya untuk memverifikasi lebih banyak aspek dari penanganan stempel waktu? Dapatkah saya menyederhanakan lingkungan pengujian saya untuk membuat ini lebih mudah di masa depan? Dapatkah saya membayangkan beberapa alat yang akan membuat ini lebih mudah, dan jika demikian, dapatkah saya menemukan alat seperti itu di Google? "Dll)
sumber
Saya sangat tidak setuju dengan Anda di sini. Itu adalah bug di perpustakaan , sebenarnya agak berbahaya. Mereka telah mengubah tipe semantik dari nilai balik, tetapi tidak mengubah jenis program dari nilai balik. Ini dapat mendatangkan semua jenis malapetaka, terutama jika ini adalah versi kecil, tetapi juga jika itu adalah versi utama.
Katakanlah sebaliknya perpustakaan mengembalikan jenis
MillisecondsSinceEpoch
, pembungkus sederhana yang menampung along
. Ketika mereka mengubahnya keNanosecondsSinceEpoch
nilai, kode Anda akan gagal dikompilasi, dan jelas akan mengarahkan Anda ke tempat-tempat di mana Anda perlu melakukan perubahan. Perubahan tidak bisa merusak program Anda secara diam-diam.Lebih baik lagi akan menjadi
TimeSinceEpoch
objek yang dapat mengadaptasi antarmuka itu sebagai lebih presisi ditambahkan, seperti menambahkan#toLongNanoseconds
metode di samping#toLongMilliseconds
metode, tidak memerlukan perubahan pada kode Anda sama sekali.Masalah berikutnya adalah bahwa Anda tidak memiliki satu set tes integrasi yang dapat diandalkan ke perpustakaan. Anda harus menulis itu. Lebih baik membuat antarmuka di perpustakaan itu untuk merangkumnya dari sisa aplikasi Anda. Beberapa jawaban lain membahas hal ini (dan banyak lagi yang terus bermunculan saat saya mengetik). Tes integrasi harus dijalankan lebih jarang daripada tes unit Anda. Itu sebabnya memiliki lapisan penyangga membantu. Pisahkan tes integrasi Anda ke area yang terpisah (atau beri nama berbeda) sehingga Anda dapat menjalankannya sesuai kebutuhan, tetapi tidak setiap kali Anda menjalankan tes unit Anda.
sumber
...Ex()
metode di Win32API). Jika ini tidak layak, "melanggar" kontrak dengan mengganti nama fungsi (atau jenis kembalinya) akan lebih baik daripada mengubah perilaku.Anda memerlukan tes integrasi dan sistem.
Tes unit sangat bagus untuk memverifikasi bahwa kode Anda berperilaku seperti yang Anda harapkan. Ketika Anda menyadari, itu tidak melakukan apa pun untuk menantang asumsi Anda atau memastikan harapan Anda waras.
Kecuali jika produk Anda hanya memiliki sedikit interaksi dengan sistem eksternal, atau berinteraksi dengan sistem yang sangat terkenal, stabil, dan terdokumentasi sehingga dapat diejek dengan percaya diri (ini jarang terjadi di dunia nyata) - unit test tidak cukup.
Semakin tinggi level tes Anda, semakin mereka akan melindungi Anda dari hal-hal yang tidak terduga. Itu membutuhkan biaya (kenyamanan, kecepatan, kerapuhan ...), jadi unit test harus tetap menjadi dasar pengujian Anda, tetapi Anda membutuhkan lapisan lain, termasuk - akhirnya - sedikit pengujian manusia yang sangat membantu dalam menangkap hal-hal bodoh yang tak seorang pun pikirkan.
sumber
Cara terbaik adalah membuat prototipe minimal, dan memahami bagaimana perpustakaan bekerja dengan tepat. Dengan melakukan itu, Anda akan memperoleh pengetahuan tentang perpustakaan dengan dokumentasi yang buruk. Prototipe dapat berupa program minimalis yang menggunakan perpustakaan itu dan melakukan fungsinya.
Kalau tidak, tidak masuk akal untuk menulis unit test, dengan persyaratan setengah didefinisikan dan pemahaman sistem yang lemah.
Adapun masalah spesifik Anda - tentang menggunakan metrik yang salah: Saya akan memperlakukannya sebagai perubahan persyaratan. Setelah Anda mengenali masalah, ubah unit test dan kodenya.
sumber
Jika Anda menggunakan perpustakaan yang populer dan stabil, maka Anda mungkin bisa berasumsi bahwa itu tidak akan mempermainkan Anda. Tetapi jika hal-hal seperti apa yang Anda gambarkan terjadi dengan perpustakaan ini, maka jelas, ini bukan satu. Setelah pengalaman buruk ini, setiap kali ada yang salah dalam interaksi Anda dengan perpustakaan ini, Anda perlu memeriksa tidak hanya kemungkinan bahwa Anda telah membuat kesalahan, tetapi juga, kemungkinan bahwa perpustakaan mungkin telah membuat kesalahan. Jadi, katakanlah ini adalah perpustakaan yang Anda "tidak yakin" tentangnya.
Salah satu teknik yang digunakan dengan perpustakaan yang kami "tidak yakin" adalah dengan membangun lapisan menengah antara sistem kami dan perpustakaan tersebut, yang abstrak fungsi yang ditawarkan oleh perpustakaan, menegaskan bahwa harapan kami terhadap perpustakaan itu benar, dan juga sangat menyederhanakan hidup kita di masa depan, haruskah kita memutuskan untuk memberikan perpustakaan itu boot dan menggantinya dengan perpustakaan lain yang berperilaku lebih baik.
sumber
assert
kunci (atau fungsi, atau fasilitas, tergantung pada bahasa apa yang Anda gunakan,) adalah teman Anda. Saya tidak berbicara tentang pernyataan dalam tes unit / integrasi, saya mengatakan bahwa lapisan isolasi harus sangat berat dengan pernyataan, menyatakan segala sesuatu yang tegas tentang perilaku perpustakaan.