Dua cara untuk membuat unit test yang andal

Dipercayai bahwa unit test tidak diperlukan. Hanya setengah kebenaran yang tersembunyi di dalamnya. Dan informasi asli tentang perilaku program akan terungkap hanya ketika kami mengumpulkannya dalam tes integrasi.

Ada alasan untuk ini, tetapi apakah unit test benar-benar tidak lengkap dan dapatkah mereka dibuat lebih andal? Berapa banyak alasan untuk ketidaklengkapan mereka?

Misalkan kita memiliki dua komponen unit-test-cover, Caller dan Callee. Penelepon memanggil Callee dengan argumen dan entah bagaimana menggunakan objek yang dikembalikan. Setiap komponen memiliki set dependensi sendiri, yang kami rendam.

Berapa banyak skenario di mana komponen-komponen ini berperilaku secara tak terduga selama integrasi?

Skenario pertama adalah masalah eksternal untuk kedua komponen . Misalnya, keduanya bergantung pada status database, otorisasi, variabel lingkungan, variabel global, cookie, file, dll. Menilai ini cukup sederhana, karena bahkan dalam program yang sangat besar biasanya ada sejumlah poin pertentangan.

Masalahnya dapat dipecahkan, jelas, baik melalui desain ulang dengan mengurangi ketergantungan,
atau kami secara langsung mensimulasikan kemungkinan kesalahan dalam skenario tingkat atas, yaitu, kami memperkenalkan komponen CallingStrategy (OffendingCaller, OffendedCallee) {}, dan mensimulasikan penanganan kecelakaan dan kesalahan Callee di CallingStrategy. Untuk ini, tes integrasi tidak diperlukan, tetapi diperlukan pemahaman bahwa perilaku spesifik dari salah satu komponen menimbulkan risiko bagi komponen lain, dan akan lebih baik untuk mengisolasi skenario ini menjadi komponen.

Skenario kedua: masalahnya ada di antarmuka objek yang dapat diintegrasikan, mis. keadaan yang tidak perlu dari salah satu objek telah bocor ke yang lain .

Sebenarnya, ini adalah cacat pada antarmuka yang memungkinkan ini. Solusi untuk masalah ini juga cukup jelas - mengetik dan mempersempit antarmuka, validasi awal parameter.

Seperti yang bisa kita lihat, kedua alasan itu sangat biasa, tetapi akan lebih baik untuk mengartikulasikan dengan jelas bahwa tidak ada yang lain.

Jadi, jika kami memeriksa kelas kami untuk 1) keadaan internal dan 2) ketergantungan eksternal, maka kami tidak memiliki alasan untuk meragukan keandalan pengujian unit.

(Di suatu tempat di sudut, seorang programmer fungsional menangis diam-diam dengan kata-kata "saya bilang begitu," tetapi tidak tentang itu sekarang).

Tapi kita bisa melupakan atau melewatkan semacam kecanduan!

Dapat diperkirakan dengan kasar. Misalkan ada sepuluh skenario di setiap komponen. Kami melewatkan satu skenario dari sepuluh. Misalnya, Callee tiba-tiba mengembalikan nol, dan Caller tiba-tiba menerima NullPointerException. Kita perlu membuat kesalahan dua kali, yang berarti kemungkinan jatuh di suatu tempat adalah 1/100. Sulit membayangkan bahwa skenario integrasi untuk dua elemen akan menangkap ini. Untuk banyak komponen yang disebut secara berurutan dalam uji integrasi, kemungkinan menangkap beberapa kesalahan meningkat, yang berarti bahwa semakin lama tumpukan tes integrasi, dan semakin banyak skenario, semakin dibenarkan itu.

(Matematika sebenarnya dari akumulasi kesalahan, tentu saja, jauh lebih rumit, tetapi hasilnya tidak jauh berbeda).

Namun, dalam proses melakukan tes integrasi, kita dapat mengharapkan peningkatan signifikan dalam kebisingan dari dependensi yang rusak dan waktu yang signifikan dihabiskan untuk menemukan bug, mereka juga sebanding dengan panjang tumpukan.

Yaitu, ternyata tes integrasi diperlukan jika tes unit buruk atau hilang . Misalnya, ketika hanya skrip yang valid diperiksa di setiap unit test, ketika mereka menggunakan antarmuka yang terlalu lebar dan tidak menganalisis dependensi umum.

Source: https://habr.com/ru/post/id473720/


All Articles