Muat pengujian dengan belalang

Pengujian beban tidak begitu diminati dan tersebar luas seperti jenis pengujian lainnya - tidak ada begitu banyak alat yang memungkinkan Anda melakukan pengujian seperti itu, tetapi sederhana dan nyaman umumnya dapat dihitung dengan jari satu tangan.

Ketika datang ke pengujian kinerja - pertama-tama, semua orang berpikir tentang JMeter - itu pasti alat paling terkenal dengan jumlah plugin terbesar. Saya tidak pernah menyukai JMeter karena antarmuka yang tidak jelas dan ambang masuk yang tinggi, segera setelah itu diperlukan untuk menguji aplikasi non-Hello World.

Dan sekarang, terinspirasi oleh keberhasilan pengujian di dua proyek berbeda, saya memutuskan untuk berbagi informasi tentang perangkat lunak yang relatif sederhana dan nyaman - Locust

Bagi mereka yang terlalu malas untuk ikut campur, saya merekam video:



Apa ini


Alat open source yang memungkinkan Anda menentukan skenario pemuatan dengan kode Python yang mendukung beban terdistribusi dan, seperti yang diklaim penulis, digunakan untuk pengujian stres Battlelog untuk seri game Battlefild (segera menawan)

Dari pro:

  • dokumentasi sederhana termasuk contoh salin-tempel. Anda dapat memulai pengujian, bahkan hampir tanpa keterampilan pemrograman.
  • "Di balik tudung" menggunakan perpustakaan permintaan (HTTP for people). Dokumentasinya dapat digunakan sebagai lembar contekan tambahan dan tes debit
  • Dukungan Python - Saya hanya suka bahasa
  • Paragraf sebelumnya memberikan cross-platform untuk menjalankan tes
  • Server web Flask sendiri untuk menampilkan hasil tes

Dari minus:

  • No Capture & Replay - semua tangan
  • Hasil paragraf sebelumnya - Anda perlu otak. Seperti halnya Postman, Anda perlu memahami cara kerja HTTP.
  • Dibutuhkan keterampilan pemrograman minimal
  • Model beban linier - yang segera membuat marah penggemar untuk menghasilkan pengguna "menurut Gauss"

Proses pengujian


Setiap pengujian adalah tugas kompleks yang memerlukan perencanaan, persiapan, pemantauan implementasi, dan analisis hasil. Selama pengujian stres, jika memungkinkan, adalah mungkin dan perlu untuk mengumpulkan semua data yang mungkin yang dapat mempengaruhi hasil:

  • Perangkat keras server (CPU, RAM, ROM)
  • Perangkat lunak server (OS, versi server, JAVA, .NET, dll., Basis data dan jumlah data itu sendiri, server dan log aplikasi pengujian)
  • Bandwidth jaringan
  • Kehadiran server proxy, load balancers, dan perlindungan DDOS
  • Memuat data pengujian (jumlah pengguna, waktu respons rata-rata, jumlah permintaan per detik)

Contoh-contoh yang diuraikan di bawah ini dapat diklasifikasikan sebagai pengujian beban fungsional kotak hitam. Bahkan tanpa mengetahui apa pun tentang aplikasi yang sedang diuji dan tanpa akses ke log, kita dapat mengukur kinerjanya.

Sebelum Anda mulai


Untuk menguji tes beban dalam praktik, saya menggunakan server web sederhana secara lokal https://github.com/typicode/json-server . Saya akan memberikan hampir semua contoh berikut untuknya. Saya mengambil data untuk server dari contoh online yang digunakan - https://jsonplaceholder.typicode.com/
Untuk menjalankannya, nodeJS diperlukan.

Spoiler yang jelas : seperti halnya pengujian keamanan - lebih baik melakukan eksperimen dengan pengujian stres pada kucing secara lokal, tanpa memuat layanan online sehingga Anda tidak dilarang

Untuk memulai, Python juga diperlukan - dalam semua contoh saya akan menggunakan versi 3.6, serta belalang itu sendiri (pada saat penulisan, versi 0.9.0). Itu dapat diinstal dengan perintah

python -m pip install locustio 

Detail instalasi dapat ditemukan di dokumentasi resmi.

Parsing Contoh


Selanjutnya kita perlu file uji. Saya mengambil contoh dari dokumentasi, karena sangat sederhana dan mudah:

 from locust import HttpLocust, TaskSet def login(l): l.client.post("/login", {"username":"ellen_key", "password":"education"}) def logout(l): l.client.post("/logout", {"username":"ellen_key", "password":"education"}) def index(l): l.client.get("/") def profile(l): l.client.get("/profile") class UserBehavior(TaskSet): tasks = {index: 2, profile: 1} def on_start(self): login(self) def on_stop(self): logout(self) class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 5000 max_wait = 9000 

Itu saja! Ini benar-benar cukup untuk memulai tes! Mari kita lihat contoh sebelum kita mulai.

Melewati impor, di bagian paling awal kita melihat 2 fungsi login dan logout yang hampir identik, terdiri dari satu baris. l.client - objek sesi HTTP yang dengannya kita akan membuat sebuah beban. Kami menggunakan metode POST, yang hampir identik dengan yang ada di pustaka permintaan. Hampir - karena dalam contoh ini kita menyampaikan sebagai argumen pertama bukan URL lengkap, tetapi hanya sebagian saja - layanan tertentu.

Argumen kedua melewati data - dan saya tidak bisa tidak melihat bahwa sangat nyaman untuk menggunakan kamus Python, yang secara otomatis dikonversi ke json

Anda juga dapat mencatat bahwa kami tidak memproses hasil permintaan dengan cara apa pun - jika berhasil, hasilnya (misalnya, cookie) akan disimpan dalam sesi ini. Jika kesalahan terjadi, itu akan dicatat dan ditambahkan ke statistik tentang beban.

Jika kami ingin tahu apakah kami telah menulis permintaan dengan benar, kami selalu dapat memeriksanya sebagai berikut:

 import requests as r response=r.post(base_url+"/login",{"username":"ellen_key","password":"education"}) print(response.status_code) 

Saya hanya menambahkan variabel base_url , yang harus berisi alamat lengkap sumber daya yang sedang diuji.

Beberapa fungsi berikutnya adalah kueri, yang akan membuat beban. Sekali lagi, kita tidak perlu memproses respons server - hasilnya akan langsung menuju statistik.

Berikutnya adalah kelas UserBehavior (nama kelasnya bisa apa saja). Seperti namanya, itu akan menggambarkan perilaku pengguna bola dalam kekosongan aplikasi yang diuji. Kami meneruskan ke properti tugas kamus metode yang akan dipanggil pengguna dan frekuensi panggilannya. Sekarang, terlepas dari kenyataan bahwa kita tidak tahu fungsi mana dan dalam urutan mana setiap pengguna akan menelepon - mereka dipilih secara acak, kami menjamin bahwa fungsi indeks akan dipanggil rata-rata 2 kali lebih sering daripada fungsi profil .

Selain perilaku, TaskSet kelas induk memungkinkan Anda untuk menentukan 4 fungsi yang dapat dilakukan sebelum dan sesudah pengujian. Urutan panggilan adalah sebagai berikut:

  1. setup - disebut 1 kali pada awal UserBehavior (TaskSet) - tidak dalam contoh
  2. on_start - dipanggil 1 kali oleh setiap pengguna baru pemuatan saat startup
  3. tugas - pelaksanaan tugas itu sendiri
  4. on_stop - dipanggil satu kali oleh setiap pengguna saat tes selesai bekerja
  5. teardown - disebut 1 kali ketika TaskSet keluar - itu juga tidak ada dalam contoh

Perlu disebutkan di sini bahwa ada 2 cara untuk mendeklarasikan perilaku pengguna: yang pertama sudah ditunjukkan dalam contoh di atas - fungsi diumumkan sebelumnya. Cara kedua adalah mendeklarasikan metode langsung di dalam kelas UserBehavior :

 from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): def on_start(self): self.client.post("/login", {"username":"ellen_key", "password":"education"}) def on_stop(self): self.client.post("/logout", {"username":"ellen_key", "password":"education"}) @task(2) def index(self): self.client.get("/") @task(1) def profile(self): self.client.get("/profile") class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 5000 max_wait = 9000 

Dalam contoh ini, fungsi pengguna dan frekuensi panggilan mereka diatur menggunakan anotasi tugas . Secara fungsional, tidak ada yang berubah.

Kelas terakhir dari contoh ini adalah WebsiteUser (nama kelasnya bisa apa saja). Di kelas ini, kami mendefinisikan model perilaku pengguna UserBehavior *** +, serta waktu tunggu minimum dan maksimum antara panggilan ke tugas individu oleh setiap pengguna. Untuk membuatnya lebih jelas, inilah cara memvisualisasikannya:



Memulai


Jalankan server, kinerja yang akan kami uji:

 json-server --watch sample_server/db.json 

Kami juga memodifikasi file contoh sehingga dapat menguji layanan, menghapus login dan logout, mengatur perilaku pengguna:

  1. Buka halaman utama 1 kali pada awal pekerjaan
  2. Dapatkan daftar semua posting x2
  3. Tulis komentar pada posting pertama x1

 from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): def on_start(self): self.client.get("/") @task(2) def posts(self): self.client.get("/posts") @task(1) def comment(self): data = { "postId": 1, "name": "my comment", "email": "test@user.habr", "body": "Author is cool. Some text. Hello world!" } self.client.post("/comments", data) class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 1000 max_wait = 2000 

Untuk memulai pada prompt perintah, jalankan perintah

 locust -f my_locust_file.py --host=http://localhost:3000 

di mana host adalah alamat sumber daya yang diuji. Baginya alamat layanan yang ditunjukkan dalam tes akan ditambahkan.

Jika tidak ada kesalahan dalam pengujian, server beban akan mulai dan akan tersedia di http: // localhost: 8089 /



Seperti yang Anda lihat, server yang akan kami uji ditunjukkan di sini - ke URL inilah alamat layanan dari file uji akan ditambahkan.

Juga di sini kita dapat menunjukkan jumlah pengguna untuk memuat dan pertumbuhannya per detik.
Pada tombolnya, kita mulai memuat!



Hasil


Setelah waktu tertentu, kami menghentikan tes dan melihat hasil pertama:

  1. Seperti yang diharapkan, masing-masing dari 10 pengguna yang dibuat di awal pergi ke halaman utama
  2. Daftar posting rata-rata dibuka 2 kali lebih sering daripada komentar ditulis
  3. Ada waktu respon rata-rata dan rata-rata untuk setiap operasi, jumlah operasi per detik sudah data yang berguna, meskipun sekarang ambil dan bandingkan dengan hasil yang diharapkan dari persyaratan

Pada tab kedua, Anda dapat melihat grafik muat secara real time. Jika server crash pada beban tertentu atau perilakunya berubah, ini akan segera terlihat pada grafik.



Pada tab ketiga, Anda dapat melihat kesalahan - dalam kasus saya, ini adalah kesalahan klien. Tetapi jika server mengembalikan kesalahan 4XX atau 5XX, teksnya akan ditulis di sini
Jika kesalahan terjadi pada kode teks Anda, itu akan jatuh ke tab Pengecualian. Sejauh ini saya memiliki kesalahan paling umum terkait dengan menggunakan perintah print () dalam kode - ini bukan cara terbaik untuk login :)

Pada tab terakhir, Anda dapat mengunduh semua hasil tes dalam format csv

Apakah hasil ini relevan? Mari kita cari tahu. Paling sering, persyaratan kinerja (jika ada dinyatakan sama sekali) terdengar seperti ini: waktu buka halaman rata-rata (respons server) harus kurang dari N detik dengan beban pengguna M. Tidak benar-benar menentukan apa yang harus dilakukan pengguna. Dan saya suka belalang untuk ini - ia menciptakan aktivitas sejumlah pengguna tertentu yang secara acak melakukan tindakan yang diharapkan dari pengguna.

Jika kita perlu melakukan benchmark - untuk mengukur perilaku sistem pada beban yang berbeda, kita dapat membuat beberapa kelas perilaku dan melakukan beberapa tes pada beban yang berbeda.

Sudah cukup untuk memulai. Jika Anda menyukai artikel ini, saya berencana untuk menulis tentang:

  • skenario pengujian kompleks di mana hasil dari satu langkah digunakan sebagai berikut
  • pemrosesan respons server, seperti mungkin salah bahkan jika HTTP 200 OK telah tiba
  • kesulitan tidak jelas yang dapat ditemui dan bagaimana cara mengatasinya
  • pengujian tanpa menggunakan UI
  • pengujian beban terdistribusi

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


All Articles