Pengujian antarmuka web yang tidak jelas. Transkrip laporan





Pada awal tahun ini, Tenzor mengadakan pertemuan di kota Ivanovo, di mana saya membuat presentasi tentang eksperimen dengan pengujian antarmuka yang tidak jelas. Berikut adalah transkrip dari laporan ini.



Kapan monyet akan mengganti semua QA? Apakah mungkin untuk mengabaikan pengujian manual dan UI autotests, menggantinya dengan fuzzing? Seperti apa diagram status dan transisi lengkap untuk aplikasi TODO sederhana? Contoh implementasi dan bagaimana fuzzing tersebut bekerja lebih jauh di bawah pemotongan.



Halo! Nama saya Sergey Dokuchaev. Selama 7 tahun terakhir saya telah melakukan pengujian dalam segala bentuknya di Tenzor.







Kami memiliki lebih dari 400 orang yang bertanggung jawab atas kualitas produk kami. 60 di antaranya didedikasikan untuk otomatisasi, keamanan, dan pengujian kinerja. Untuk mendukung puluhan ribu tes E2E, memantau indikator kinerja ratusan halaman dan mengidentifikasi kerentanan pada skala industri, Anda perlu menggunakan alat dan metode yang telah teruji dan teruji waktu dalam pertempuran.







Dan, sebagai aturan, mereka membicarakan kasus-kasus seperti itu di konferensi. Namun selain itu, masih banyak hal menarik yang masih sulit diterapkan dalam skala industri. Itu menarik dan mari kita bicarakan.







Dalam film "The Matrix" di salah satu adegannya Morpheus menawarkan Neo untuk memilih pil berwarna merah atau biru. Thomas Anderson bekerja sebagai programmer dan kami ingat pilihan apa yang dia buat. Jika dia seorang penguji terkenal, dia akan melahap kedua tablet untuk melihat bagaimana sistem akan berperilaku dalam kondisi non-standar.



Menggabungkan pengujian manual dan autotest hampir menjadi standar. Pengembang paling tahu cara kerja kode mereka dan menulis pengujian unit, penguji fungsional memeriksa fungsionalitas baru atau yang sering berubah, dan semua regresi mengarah ke berbagai pengujian otomatis.



Namun, dalam membuat dan memelihara autotest, tiba-tiba tidak ada banyak pekerjaan otomatis dan manual:



  1. Anda perlu mencari tahu apa dan bagaimana cara mengujinya.
  2. Anda perlu menemukan elemen di halaman, mengarahkan pencari lokasi yang diperlukan ke Objek Halaman.
  3. Tulis dan debug kode.
  4. β€” . / , , ROI .






Untungnya, tidak ada dua atau tiga tablet di dunia pengujian. Dan keseluruhan hamburan: pengujian semantik, metode formal, pengujian fuzzing, solusi berbasis AI. Dan bahkan lebih banyak kombinasi.







Penegasan bahwa setiap monyet yang akan mengetik di mesin tik untuk waktu yang sangat lama akan dapat mengetik teks tertentu sebelumnya telah berakar dalam pengujian. Kedengarannya bagus, kita dapat membuat satu program tanpa henti mengklik layar di tempat acak dan akhirnya kita dapat menemukan semua kesalahan.







Katakanlah kita membuat TODO seperti itu dan ingin memeriksanya. Kami mengambil layanan atau alat yang sesuai dan melihat monyet beraksi:







Dengan prinsip yang sama, kucing saya entah bagaimana, berbaring di atas keyboard, secara tidak dapat ditarik kembali merusak presentasi dan harus melakukannya lagi:







Akan lebih mudah bila setelah 10 tindakan aplikasi melontarkan pengecualian. Di sini monyet kita segera memahami bahwa kesalahan telah terjadi, dan kita dapat memahami dari log setidaknya kira-kira bagaimana hal itu berulang. Bagaimana jika kesalahan terjadi setelah 100 ribu klik acak dan tampak seperti respons yang valid? Satu-satunya keuntungan signifikan dari pendekatan ini adalah kesederhanaan maksimum - Anda menekan tombol dan selesai.







Kebalikan dari pendekatan ini adalah metode formal.







Ini adalah foto New York pada tahun 2003. Salah satu tempat paling terang dan paling ramai di planet ini, Times Square hanya diterangi oleh lampu depan mobil yang lewat. Tahun itu, jutaan orang di Kanada dan Amerika Serikat menemukan diri mereka di Zaman Batu selama tiga hari karena pemadaman pembangkit listrik bertingkat. Salah satu alasan utama insiden itu adalah kesalahan kondisi balapan di perangkat lunak.



Sistem kritis-kesalahan memerlukan pendekatan khusus. Metode yang tidak mengandalkan intuisi dan keterampilan, tetapi matematika disebut formal. Dan tidak seperti pengujian, mereka memungkinkan Anda untuk membuktikan bahwa tidak ada kesalahan dalam kode. Model jauh lebih sulit untuk dibuat daripada menulis kode yang seharusnya mereka uji. Dan penggunaannya lebih seperti membuktikan teorema dalam kuliah tentang kalkulus.







Slide menunjukkan bagian dari model algoritme dua jabat tangan yang ditulis dalam bahasa TLA +. Saya pikir sudah jelas bagi semua orang bahwa menggunakan alat ini saat memeriksa cetakan di situs sebanding dengan membangun Boeing 787 untuk menguji sifat aerodinamis tanaman jagung.







Bahkan dalam industri medis, kedirgantaraan, dan perbankan yang rawan kesalahan secara tradisional, jenis pengujian ini sangat jarang. Tetapi pendekatan itu sendiri tidak tergantikan jika kerugian akibat kesalahan dihitung dalam jutaan dolar atau dalam kehidupan manusia.



Pengujian fuzzing sekarang paling sering dilihat dalam konteks pengujian keamanan. Dan skema tipikal yang mendemonstrasikan pendekatan ini, kami ambil dari panduan OWASP :







Di sini kami memiliki situs yang perlu diuji, ada database dengan data uji dan alat yang akan kami gunakan untuk mengirimkan data yang ditentukan ke situs. Vektor adalah string biasa yang diperoleh secara empiris. String seperti itu kemungkinan besar mengarah pada penemuan kerentanan. Ini seperti tanda kutip yang banyak orang secara otomatis menempatkan angka di URL dari bilah alamat.







Dalam kasus yang paling sederhana, kami memiliki layanan yang menerima permintaan dan browser yang mengirimkannya. Pertimbangkan kasus dengan mengubah tanggal lahir pengguna.







Pengguna memasukkan tanggal baru dan mengklik tombol "Simpan". Permintaan dikirim ke server dengan data dalam format json.







Dan jika semuanya baik-baik saja, maka layanan merespons dengan kode dua ratus.







Sangat mudah untuk bekerja dengan json secara terprogram dan kami dapat mengajarkan alat fuzzing kami untuk menemukan dan menentukan tanggal dalam data yang dikirimkan. Dan dia akan mulai mengganti berbagai nilai untuk mereka, misalnya, itu akan mengirimkan bulan yang tidak ada.







Dan jika sebagai tanggapan kami menerima pengecualian alih-alih pesan tentang tanggal tidak valid, maka kami memperbaiki kesalahan tersebut.



Mengaburkan API tidaklah sulit. Di sini kami memiliki parameter yang ditransmisikan di json, di sini kami mengirim permintaan, menerima respons, dan menganalisisnya. Bagaimana dengan GUI?



Mari kita lihat program dari contoh pengujian demo lagi. Di dalamnya, Anda dapat menambahkan tugas baru, menandai selesai, menghapus, dan melihat keranjang.







Jika kita berurusan dengan dekomposisi, kita akan melihat bahwa antarmuka bukanlah monolit tunggal, tetapi juga terdiri dari elemen-elemen terpisah:







Tidak banyak yang bisa kami lakukan dengan masing-masing kontrol. Kami memiliki mouse dengan dua tombol, roda dan keyboard. Anda dapat mengklik salah satu elemen, menggerakkan kursor mouse ke atasnya, Anda dapat memasukkan teks ke dalam bidang teks.



Jika kita memasukkan beberapa teks di bidang teks dan menekan Enter, maka halaman kita akan beralih dari satu keadaan ke keadaan lain: Secara







skematis dapat digambarkan seperti ini:







Dari keadaan ini kita bisa pergi ke ketiga dengan menambahkan tugas lain ke daftar:







Dan kita bisa menghapus yang ditambahkan tugas, kembali ke status pertama:







Atau klik pada label TODO dan tetap di status kedua:







Dan sekarang mari kita coba menerapkan Bukti Konsep dari pendekatan ini.







Untuk bekerja dengan browser, kami akan menggunakan chromedriver, kami akan bekerja dengan diagram status dan transisi melalui pustaka python NetworkX, dan kami akan menggambar melalui yEd.







Kami meluncurkan browser, membuat contoh grafik, di mana bisa ada banyak koneksi dengan arah berbeda antara dua simpul. Dan kami membuka aplikasi kami.







Sekarang kita harus mendeskripsikan status aplikasi. Karena algoritme kompresi gambar, kita dapat menggunakan ukuran gambar PNG sebagai pengenal status dan, melalui metode __eq__, mengimplementasikan perbandingan status ini dengan yang lain. Melalui atribut iterated, kami memperbaiki bahwa semua tombol telah diklik, nilai telah dimasukkan ke semua bidang dalam status ini, untuk mengecualikan pemrosesan berulang.







Kami menulis algoritma dasar yang akan melewati seluruh aplikasi. Di sini kami memperbaiki status pertama dalam grafik, di loop kami mengklik semua elemen dalam status ini dan memperbaiki status yang dihasilkan. Selanjutnya, pilih status belum diproses berikutnya dan ulangi langkah-langkahnya.







Saat mengaburkan kondisi saat ini, kita harus setiap saat kembali ke kondisi ini dari yang baru. Untuk melakukan ini, kami menggunakan fungsi nx.shortest_path, yang akan mengembalikan daftar elemen yang perlu diklik untuk beralih dari status dasar ke status saat ini.

Untuk menunggu akhir dari respon aplikasi untuk tindakan kita, fungsi tunggu menggunakan API Tugas Panjang Jaringan, yang menunjukkan apakah JS sedang sibuk dengan pekerjaan apa pun.



Mari kembali ke aplikasi kita. Keadaan awalnya adalah sebagai berikut:







Setelah sepuluh iterasi aplikasi, kita akan mendapatkan diagram status dan transisi berikut:







Setelah 22 iterasi, ini adalah sebagai berikut:







Jika kita menjalankan skrip kita selama beberapa jam, maka tiba-tiba akan melaporkan bahwa ia telah melewati semua kemungkinan status, setelah menerima diagram berikut:







Jadi, dengan aplikasi demo sederhana kita berhasil. Dan apa yang terjadi jika Anda menyetel skrip ini pada aplikasi web nyata. Dan akan ada kekacauan:







Tidak hanya terjadi perubahan di backend, halaman itu sendiri terus digambar ulang saat bereaksi terhadap pengatur waktu atau peristiwa, saat melakukan tindakan yang sama, kita bisa mendapatkan status yang berbeda. Tetapi bahkan dalam aplikasi semacam itu, Anda dapat menemukan bagian fungsionalitas yang dapat ditangani oleh skrip kami tanpa modifikasi yang signifikan.

Ambil untuk pengujianHalaman otentikasi VLSI:







Dan untuk itu cukup cepat ternyata untuk membangun diagram lengkap status dan transisi:











Luar biasa! Kami sekarang dapat melintasi semua status aplikasi. Dan murni dalam teori, temukan semua kesalahan yang bergantung pada tindakan. Tetapi bagaimana Anda mengajarkan program untuk memahami bahwa ada kesalahan di depannya?



Dalam pengujian, respon program selalu dibandingkan dengan standar tertentu yang disebut oracle. Mereka dapat berupa spesifikasi teknis, mock-up, analog program, versi sebelumnya, pengalaman penguji, persyaratan formal, kasus uji, dll. Kami juga dapat menggunakan beberapa nubuat ini di alat kami.







Mari kita pertimbangkan pola terakhir "sebelumnya berbeda". Autotests terlibat dalam pengujian regresi.



Mari kembali ke grafik setelah 10 iterasi TODO:







Mari kita pecahkan kode yang bertanggung jawab untuk membuka keranjang belanja dan menjalankan 10 iterasi lagi:







Dan kemudian kita membandingkan dua grafik dan menemukan perbedaan dalam status:







Kita dapat meringkas untuk pendekatan ini:







Seperti berdiri, teknik ini dapat digunakan untuk menguji aplikasi kecil dan mengidentifikasi kesalahan yang jelas atau regresi. Agar teknik lepas landas untuk aplikasi besar dengan GUI yang tidak stabil, diperlukan peningkatan yang signifikan.

Semua kode sumber dan daftar bahan bekas dapat ditemukan di repositori: https://github.com/svdokuchaev/venom . Bagi yang ingin memahami kegunaan fuzzing dalam pengujian, saya sangat merekomendasikan The Fuzzing Book . Di sana, di salah satu bagian, pendekatan yang sama untuk mem-fuzzing bentuk html sederhana dijelaskan .






All Articles