65.000.000.000 tes untuk dijalankan

50

Saya ditanya tentang bagaimana menjalankan serangkaian 65.000.000.000 tes dan saya bertanya-tanya apakah itu normal untuk memiliki proyek dengan sejumlah besar tes.

Sudahkah Anda bekerja dalam proyek dengan karakteristik ini?

juanpavergara
sumber
32
65 Miliar (10e9) tes? Apakah ini masalah praktis atau pertanyaan wawancara?
40
Saya akan sangat tertarik untuk mengetahui siapa yang menulis 65 miliar tes dan berapa tahun yang dibutuhkan.
Rig
46
Dengan 65 miliar tes, jika Anda dapat menjalankan 1000 tes / detik, itu akan memakan waktu sekitar 2 tahun untuk berjalan. 10.000 tes / detik sedikit lebih dari dua bulan. 100.000 tes / detik akan memakan waktu sekitar satu minggu. Ini menggambarkan beberapa kekuatan pemrosesan serius untuk menjalankan tes dalam jangka waktu yang masuk akal.
20
Saya tidak ingin menjadi orang yang menulis matriks keterlacakan ...
mouviciel
23
@DanPichelman - Jelas, Anda perlu menulis setengah miliar tes lagi untuk menguji apakah generator tes menghasilkan tes dengan benar.
Bobson

Jawaban:

103

Dengan 65 miliar tes, sepertinya Anda diminta menguji semua input yang mungkin. Ini tidak berguna - Anda pada dasarnya akan menguji apakah prosesor Anda berfungsi dengan benar, bukan karena kode Anda benar.

Anda seharusnya menguji kelas kesetaraan sebagai gantinya. Ini secara drastis akan mengurangi rentang input pengujian Anda.

Juga pertimbangkan apakah Anda dapat membagi sistem Anda menjadi bagian-bagian yang lebih kecil. Setiap bagian akan lebih mudah diuji secara terpisah, dan kemudian Anda dapat melakukan beberapa tes integrasi yang menyatukan semua bagian.

Jika Anda masih menginginkan kepastian bahwa beberapa kombinasi input tersebut berfungsi, mungkin Anda bisa mencoba pengujian fuzz . Anda akan mendapatkan beberapa manfaat dari pengujian banyak input berbeda, tetapi tanpa menjalankan semuanya 65 miliar.

M. Dudley
sumber
12
+1, terutama untuk "Anda pada dasarnya akan menguji bahwa prosesor Anda berfungsi dengan benar"
Doc Brown
4
Untuk fungsi cukup sederhana (sedikit mengutak-atik dll) saya lakukan cenderung menguji semua nilai yang mungkin. Ini bukti-bodoh dan dengan demikian memberi saya kepercayaan diri yang jauh lebih baik daripada menguji kelas-kelas kesetaraan (diturunkan, dan berpotensi salah). Tentu saja itu tidak berfungsi lagi ketika input Anda yang mungkin masuk ke dalam miliaran.
Konrad Rudolph
39

Jika ini adalah ruang tes nyata, maka Anda tidak ingin mendekati itu.

Seluruh pekerjaan penguji adalah untuk menyeimbangkan antara pengujian cukup menyeluruh untuk yakin Anda mendapatkan hasil yang "benar" dan menulis beberapa tes cukup bahwa mereka dapat dijalankan dalam jumlah waktu yang wajar.

Banyak tes dapat diabstraksikan menjadi "kelas ekivalensi", yang berarti bahwa alih-alih menjalankan 3 miliar tes, Anda menjalankan 1 yang memberi Anda tingkat kepercayaan yang wajar bahwa semua tes lain di kelas ekivalensi itu akan berjalan dengan sukses, jika Anda memutuskan untuk menyia-nyiakan waktu menjalankannya.

Anda harus memberi tahu siapa pun yang berpikir menjalankan 65 miliar tes bahwa mereka perlu melakukan tes abstrak pekerjaan yang lebih baik ke dalam kelas kesetaraan.

dsw88
sumber
+1 pada pengujian secara menyeluruh tetapi efisien.
Marco
23

Kemungkinan besar, Anda mencapai angka 65 miliar tes dengan menghitung semua kemungkinan kombinasi input ke dalam sistem yang diuji, atau dengan menghitung kompleksitas cyclomatic dan dengan asumsi tes harus ditulis untuk masing-masing jalur eksekusi unik ini.

Ini bukan bagaimana tes nyata ditulis, karena seperti poster dan komentator lain telah mengindikasikan, kekuatan teknis diperlukan untuk mengeksekusi 65 miliartes mengejutkan. Ini akan seperti menulis tes yang menggunakan metode untuk menambahkan dua bilangan bulat dengan memasukkan setiap permutasi yang mungkin dari dua nilai 32-bit dan memeriksa hasilnya. Ini kegilaan total. Anda harus menarik garis dan mengidentifikasi subset dari semua kasus uji yang mungkin, yang di antara mereka akan memastikan bahwa sistem akan berperilaku seperti yang diharapkan di seluruh rentang input. Misalnya. Anda menguji menambahkan beberapa angka "biasa", Anda menguji beberapa skenario angka negatif, Anda menguji batas teknis seperti skenario overflow, dan Anda menguji setiap skenario yang menghasilkan kesalahan. Seperti disebutkan, berbagai jenis tes ini melakukan "kelas ekivalensi"; mereka memungkinkan Anda untuk mengambil sampel representatif dari kemungkinan input, bersama dengan "pencilan" yang diketahui,

Pertimbangkan salah satu kode dasar katas, Generator Angka Romawi. Tugas, yang harus dilakukan menggunakan teknik TDD dalam gaya "dojo", adalah menulis fungsi yang dapat menerima angka dari 1 hingga 3000 dan menghasilkan angka Romawi yang benar untuk nilai angka itu.

Anda tidak memecahkan masalah ini dengan menulis 3000 unit test, satu per satu, dan meneruskannya secara bergantian. Itu kegilaan; latihan biasanya memakan waktu antara satu dan dua jam, dan Anda akan berada di sana selama berhari-hari menguji setiap nilai individu. Sebaliknya, Anda menjadi pintar. Anda mulai dengan kasus dasar paling sederhana (1 == "I"), mengimplementasikannya menggunakan strategi "kode paling" ( return "I";), dan kemudian mencari bagaimana kode yang Anda miliki akan berperilaku tidak benar dalam skenario lain yang diharapkan (2 == " II "). Bilas dan ulangi; lebih dari kemungkinan, Anda mengganti implementasi awal Anda dengan sesuatu yang mengulang karakter "I" sesering yang diperlukan (seperti return new String('I',number);). Itu jelas akan lulus ujian untuk III, jadi Anda tidak repot; sebagai gantinya, Anda menulis tes untuk 4 == "IV", yang Anda tahu implementasi saat ini menang '

Atau, dalam gaya yang lebih analitis, Anda memeriksa setiap keputusan kondisional yang dibuat oleh kode (atau perlu), dan menulis tes yang dirancang untuk memasukkan kode untuk setiap hasil yang mungkin dari setiap keputusan. Jika Anda memiliki 5 jika pernyataan (masing-masing memiliki cabang benar dan salah), masing-masing sepenuhnya independen dari yang lain, Anda kode 10 tes, bukan 32. Setiap tes akan dirancang untuk menegaskan dua hal tentang kemungkinan keputusan tertentu; pertama bahwa keputusan yang benar dibuat, dan kemudian kode dimasukkan mengingat kondisi itu benar. Anda tidak memberi kode tes untuk setiap permutasi yang memungkinkan dari keputusan independen. Jika keputusan tergantung, maka Anda harus menguji lebih banyak dari mereka dalam kombinasi, tetapi ada lebih sedikit kombinasi seperti itu karena beberapa keputusan hanya pernah dibuat ketika keputusan lain memiliki hasil tertentu.

KeithS
sumber
5

Apakah ini "normal"? Tidak Di mana "normal" didefinisikan sebagai pengalaman rata-rata atau khas. Tidak bisa mengatakan saya pernah harus mengerjakan proyek seperti itu, tetapi saya telah mengerjakan proyek di mana satu dari setiap beberapa juta bit akan terbalik. Menguji yang satu itu ... tantangan.

Apakah ini berpotensi diperlukan? Ya, itu tergantung pada jaminan dan spesifikasi proyek. Awalnya agak tidak percaya untuk memahaminya, tetapi pertanyaan Anda tidak terlalu spesifik.

Seperti orang lain (MichaelT) telah tunjukkan, waktu untuk menyelesaikan tugas ini dengan pengujian serial membuatnya tidak praktis. Jadi paralelisasi menjadi pertimbangan pertama Anda. Berapa banyak sistem pengujian yang dapat Anda berikan pada masalah ini, dan dukungan apa yang Anda miliki untuk menyusun hasil dari berbagai sistem tersebut?

Apa jaminan yang Anda miliki bahwa perangkat atau algoritma yang Anda uji direplikasi dengan andal? Perangkat lunak cukup dapat diandalkan dalam replikasi, tetapi perangkat perangkat keras (terutama generasi pertama) dapat memiliki masalah pembuatan. Kegagalan pengujian palsu dalam kasus itu dapat menunjukkan algoritma yang buruk atau perangkat tidak berkumpul dengan benar. Apakah Anda perlu membedakan antara dua kasus itu?

Anda juga harus mempertimbangkan bagaimana Anda akan memvalidasi sistem pengujian itu sendiri. Menganggap alasan yang sah untuk banyak kasus uji, Anda akan membutuhkan banyak otomatisasi. Otomasi itu perlu diperiksa untuk memastikan tidak ada kesalahan dalam membuat test case Anda. Pemeriksaan spot untuk kesalahan akan benar-benar setara dengan menemukan jarum di tumpukan jerami.

Tautan arstechnica ini mungkin atau mungkin tidak memberi wawasan tentang pertimbangan pengujian Anda. Cluster GPU biasanya digunakan untuk kata sandi crack brute force. Yang dikutip dalam artikel bisa can cycle through as many as 350 billion guesses per second, sehingga menempatkan tes 65B Anda dalam perspektif. Kemungkinan domain yang berbeda, tetapi ini menunjukkan bagaimana mendekati tugas dari sudut yang berbeda dapat menghasilkan solusi yang layak.


sumber
3

Saya tidak berpikir itu layak untuk mempertahankan 6.5e + 10 tes itu tempat pertama, jadi menjalankannya mungkin bisa diperdebatkan. Bahkan proyek terbesar, seperti Debian dengan semua paketnya, hanya memiliki total beberapa ratus juta SLOC.

Tetapi jika Anda harus menjalankan sejumlah besar tes, ada beberapa strategi.

  • Jangan jalankan semuanya. Kemungkinan besar tidak setiap tes tergantung pada setiap jalur kode. Tentukan dependensi antara subsistem dan pengujiannya, dan antara suite tes, dan Anda hanya akan dapat menjalankan tes unit yang relevan dengan perubahan tertentu, hanya tes integrasi tergantung pada tes unit ini, dll.

  • Jalankan secara paralel. Dengan basis kode yang sangat besar, Anda mungkin memiliki farm build yang besar (kembali di JetBrains, operasi yang relatif kecil, kami dulu memiliki 40-50 agen build yang berjalan di farm build / integrasi continuous IDEA saja). Karena tes unit independen, dan tes integrasi dapat menggunakan kembali kode yang sudah dibangun, tes relatif mudah diparalelkan.

  • Berhentilah berlari lebih awal. Jika Anda tahu bahwa suite tes tertentu bergantung pada fungsinya yang masuk akal pada kebenaran suite tes lain, Anda dapat memotong seluruh rantai begitu Anda melihat satu tautan gagal.

Penafian: Saya bukan insinyur pengujian profesional. Ambil yang di atas dengan sebutir garam.

9000
sumber
5
... Tentu saja, di JetBrains, agen pembangun itu bebas karena mereka mengembangkan TeamCity dan langsung memilikinya. "Operasi yang relatif kecil" lainnya kemungkinan akan mengalami serangan jantung karena memikirkan biaya awal sekitar $ 15.000 (hanya untuk perangkat lunak; tambahkan 40-50 unit blademount dan perangkat keras lainnya, dan bahkan menggunakan distro Linux gratis untuk menampung semua yang Anda inginkan. ' Aku dengan mudah berbicara gaji tahunan senior dev) dan $ 6500 biaya pemeliharaan tahunan, ditambah waktu dan keterampilan staf TI yang diperlukan untuk menjaga pertanian bersenandung bersama.
KeithS
0

Meskipun ada beberapa saran bagus di sini tentang cara mencoba menyelinap dengan lebih sedikit tes, saya sangat ragu sistem Anda hanya memiliki 65 miliar kombinasi input. Itu kurang dari 36 bit input. Mari kita asumsikan Anda sudah mengambil semua saran yang diberikan di atas.

Jika setiap tes membutuhkan waktu sekitar satu milidetik untuk berjalan dan Anda mendistribusikan tes hanya di 10 prosesor (satu PC normal), tes akan berjalan dalam sedikit lebih dari 69 hari. Itu sementara, tetapi tidak sepenuhnya tidak masuk akal. Bagikan 100 prosesor (selusin PC normal atau satu PC server masuk akal) dan tes akan selesai dalam waktu kurang dari 7 hari. Anda dapat menjalankan ini setiap minggu untuk memeriksa regresi.

Paul Scherf
sumber