Pada 14 Desember, di sebuah rapat umum di St. Petersburg, saya (Artem Sokovets), bersama dengan rekan saya, Dmitry Markelov, berbicara tentang infrastruktur saat ini untuk autotests di SberTech. Menceritakan kembali pidato kami di pos ini.

Apa itu Selenium
Selenium adalah alat otomatisasi browser web. Saat ini, alat ini adalah standar untuk otomatisasi WEB.

Ada banyak klien untuk berbagai bahasa pemrograman yang mendukung Selenium Webdriver API. Melalui WebDriver API, melalui protokol JSON Wire, interaksi terjadi dengan driver dari browser yang dipilih, yang, pada gilirannya, bekerja dengan browser yang sudah nyata, melakukan tindakan yang kita butuhkan.
Hari ini, versi stabil klien adalah Selenium 3.X.

Simon Stewart, omong-omong, berjanji untuk memperkenalkan Selenium 4.0 pada konferensi
SeleniumConf Jepang .
Selenium GRID
Pada 2008, Philippe Hanrigou mengumumkan Selenium GRID untuk membangun infrastruktur untuk autotest dengan dukungan untuk berbagai browser.

Selenium GRID terdiri dari hub dan node (node). Node hanyalah proses java. Bisa di mesin yang sama dengan Hub, bisa di mesin lain, bisa di wadah Docker. Hub pada dasarnya adalah penyeimbang untuk autotest, yang menentukan simpul yang harus dikirimi pengujian tertentu. Anda dapat menghubungkan emulator seluler ke sana.
Selenium GRID memungkinkan Anda menjalankan tes pada berbagai sistem operasi dan versi browser yang berbeda. Ini juga secara signifikan menghemat waktu ketika menjalankan sejumlah besar autotest, jika, tentu saja, autotest dijalankan secara paralel menggunakan maven-surfire-plugin atau mekanisme paralelisasi lainnya.
Tentu saja, Selenium GRID memiliki kekurangan. Saat menggunakan implementasi standar, kita harus menghadapi masalah berikut:
- restart terus-menerus dari hub dan node. Jika hub dan node tidak digunakan untuk waktu yang lama, maka dengan koneksi berikutnya, situasi mungkin terjadi ketika, saat membuat sesi pada node, sesi yang sama ini jatuh dalam batas waktu. Untuk memulihkan pekerjaan, diperlukan restart;
- membatasi jumlah node. Sangat tergantung pada tes dan pengaturan kisi. Tanpa menari dengan rebana, ia mulai melambat dengan beberapa lusin node yang terhubung;
- fungsionalitas yang kecil;
- ketidakmungkinan pembaruan tanpa berhenti sepenuhnya dari layanan.
Infrastruktur AutoTest Awal di SberTech
Sebelumnya di SberTech ada infrastruktur berikut untuk pengujian UI-otomatis. Pengguna memulai perakitan di Jenkins, yang, menggunakan plugin, beralih ke OpenStack untuk mengalokasikan mesin virtual. VM dipilih dengan "gambar" khusus dan browser yang diinginkan, dan baru kemudian autotest dijalankan pada VM ini.
Jika Anda ingin menjalankan tes di browser Chrome atau FireFox, wadah Docker menonjol. Tetapi ketika bekerja dengan IE, Anda harus menaikkan VM "bersih", yang membutuhkan waktu hingga 5 menit. Sayangnya, Internet Explorer adalah browser prioritas di perusahaan kami.

Masalah utama adalah bahwa pendekatan ini membutuhkan banyak waktu ketika menjalankan autotest di IE. Saya harus memisahkan tes pada suite dan memulai majelis secara paralel untuk mencapai setidaknya beberapa pengurangan waktu. Kami mulai berpikir tentang modernisasi.
Persyaratan Infrastruktur Baru
Mengunjungi berbagai konferensi tentang otomatisasi, pengembangan, dan DevOps (Heisenbug, SQA Days, CodeOne, SeleniumConf, dan lainnya), kami secara bertahap membentuk daftar persyaratan untuk infrastruktur baru:
- Kurangi waktu untuk menjalankan tes regresi;
- Berikan titik masuk tunggal untuk uji otomatis, yang akan memudahkan proses debugging mereka untuk spesialis otomasi. Tidak ada kasus langka ketika semuanya bekerja secara lokal, dan segera setelah tes masuk ke dalam pipa - jatuh terus menerus.
- Untuk memberikan kompatibilitas lintas-browser dan otomatisasi seluler (uji Appium).
- Tetap berpegang pada arsitektur cloud bank: Wadah Docker harus dikelola di OpenShift.
- Kurangi konsumsi memori dan CPU.
Tinjauan singkat solusi yang ada
Setelah menetapkan tugas, kami menganalisis solusi yang ada di pasar. Hal-hal utama yang kami periksa adalah produk-produk dari tim
Aerokube (Selenoid dan Bulan), solusi Alfalab (Laboratorium Alpha),
JW-Grid (Avito) dan
Zalenium .
Kerugian utama Selenoid adalah kurangnya dukungan untuk OpenShift (pembungkus atas Kubernetes). Tentang keputusan Alfalab ada
artikel tentang Habré . Ternyata menjadi Selenium Grid yang sama. Solusi Avito dijelaskan dalam
artikel . Kami melihat laporannya di konferensi Heisenbug. Itu juga memiliki kontra yang tidak kita sukai. Zalenium adalah proyek open source, juga bukan tanpa masalah.
Pro dan kontra dari solusi yang dipertimbangkan oleh kami dirangkum dalam tabel:

Sebagai hasilnya, kami memilih produk dari Aerokube - Selenoid.
Selenoid vs Moon
Selama empat bulan, kami menggunakan Selenoid untuk mengotomatisasi ekosistem Sberbank. Ini adalah solusi yang baik, tetapi Bank sedang bergerak menuju OpenShift, dan menggunakan Selenoid di OpenShift bukanlah tugas yang sepele. Kehalusannya adalah bahwa Selenoid di Kubernetes mengelola buruh pelabuhan dari yang terakhir, dan Kubernetes tidak tahu apa-apa tentang hal itu dan tidak dapat dengan benar bercanda dengan node lain. Selain itu, Selenoid di Kubernetes membutuhkan GGR (Go Grid Router) di mana penyeimbangan muatan menjadi lemah.
Setelah bereksperimen dengan Selenoid, kami menjadi tertarik pada alat Moon berbayar, yang difokuskan khusus pada bekerja dengan Kubernetes dan memiliki sejumlah keunggulan dibandingkan dengan Selenoid gratis. Ini telah berkembang selama dua tahun sekarang dan memungkinkan Anda untuk menggunakan infrastruktur untuk pengujian UI Selenium tanpa mengeluarkan uang untuk insinyur DevOps yang memiliki pengetahuan rahasia tentang cara menggunakan Selenoid di Kubernetes. Ini merupakan keuntungan penting - coba tingkatkan kluster Selenoid tanpa downtime dan mengurangi kapasitas saat menjalankan tes?

Bulan bukan satu-satunya pilihan. Misalnya, Anda dapat mengambil Zalenium yang disebutkan di atas, tetapi sebenarnya itu adalah Selenium Grid yang sama. Ini memiliki daftar lengkap sesi di dalam hub yang tersimpan di dalamnya, dan jika hub crash, maka tes berakhir. Terhadap latar belakang ini, Moon menang karena fakta bahwa ia tidak memiliki keadaan internal, sehingga jatuhnya salah satu replika pada umumnya tidak terlihat. Moon memiliki segalanya "dengan anggun" - ia dapat dimulai kembali tanpa rasa takut, tanpa menunggu akhir sesi.
Zalenium memiliki keterbatasan lain. Misalnya, tidak mendukung Kuota. Anda tidak dapat meletakkan dua salinannya untuk penyeimbang beban, karena dia tidak tahu bagaimana mendistribusikan kondisinya di antara dua "kepala" atau lebih. Dan secara umum, sulit untuk memulai di klusternya. Zalenium menggunakan PersistentVolume untuk menyimpan data: log dan rekaman tes video, tetapi ini terutama menyangkut disk di awan, dan bukan S3 yang lebih toleran terhadap kesalahan.
Infrastruktur Tes Otomatis
Infrastruktur saat ini menggunakan Moon dan OpenShift adalah sebagai berikut:

Pengguna dapat menjalankan tes secara lokal dan menggunakan server CI (dalam kasus kami, Jenkins, tetapi mungkin ada yang lain). Dalam kedua kasus, kami menggunakan RemoteWebDriver untuk mengakses OpenShift, di mana layanan dengan beberapa replika Moon digunakan. Selanjutnya, permintaan di mana peramban yang kita perlukan diindikasikan diproses di Bulan, sebagai akibatnya API Kubernetes memulai pembuatan perapian dengan peramban ini. Kemudian Moon secara langsung mem-proksi permintaan ke kontainer, di mana tes lulus.
Di akhir proses, sesi berakhir, di bawah dihapus, sumber daya dibebaskan.
Luncurkan Internet Explorer
Tentu saja ada beberapa kesulitan. Seperti yang disebutkan sebelumnya, browser target untuk kita adalah Internet Explorer - sebagian besar aplikasi kita menggunakan komponen ActiveX. Karena kami menggunakan OpenShift, wadah Docker kami berjalan di RedHat Enterprise Linux. Dengan demikian, muncul pertanyaan: bagaimana cara memulai Internet Explorer di wadah Docker ketika mesin host di Linux?
Orang-orang dari tim pengembangan Bulan membagikan keputusan mereka untuk meluncurkan Internet Explorer dan Microsoft Edge.
Kerugian dari solusi ini adalah bahwa wadah Docker harus berjalan dalam mode istimewa. Jadi, dibutuhkan 10 detik untuk menginisialisasi wadah dengan Internet Explorer setelah memulai tes, yang 30 kali lebih cepat daripada menggunakan infrastruktur sebelumnya.
Pemecahan masalah
Sebagai kesimpulan, kami ingin berbagi dengan Anda solusi untuk beberapa masalah yang kami temui selama penyebaran dan konfigurasi cluster.
Masalah pertama adalah distribusi gambar layanan. Ketika bulan memulai pembuatan browser, selain wadah dengan browser, wadah layanan tambahan diluncurkan - pencatat, pembela, perekam video.

Semua ini diluncurkan dalam satu pod. Dan jika gambar kontainer ini tidak di-cache pada node, maka mereka akan dikirim dari hub Docker. Pada tahap ini, semuanya jatuh pada kita, karena jaringan internal digunakan. Oleh karena itu, orang-orang dari Aerokube dengan cepat memasukkan pengaturan ini ke dalam konfigurasi peta. Jika Anda juga menggunakan jaringan internal, kami sarankan Anda menyiram gambar-gambar ini ke dalam registri Anda dan menentukan lintasan ke sana di peta konfigurasi bulan-config. Di file service.json, Anda perlu menambahkan bagian gambar:
"images": { "videoRecorder": "ufs-selenoid-cluster/moon-video-recorder:latest", "defender": "ufs-selenoid-cluster/defender:latest", "logger": "ufs-selenoid-cluster/logger:latest" }
Masalah berikut ini sudah diidentifikasi pada awal tes. Seluruh infrastruktur dibuat secara dinamis, tetapi tes macet setelah 30 detik dengan kesalahan berikut:
Driver info: org.openqa.selenium.remote.RemoteWebDriver Org.openqa.selenium.WebDriverException: <html><body><h1>504 Gateway Time-out</h1> The server didn't respond in time.
Mengapa ini terjadi? Faktanya adalah bahwa pengujian melalui RemoteWebDriver awalnya mengacu pada OpenShift lapisan routing, yang bertanggung jawab untuk berinteraksi dengan lingkungan eksternal. Peran lapisan ini adalah Haproxy, yang mengalihkan permintaan ke kontainer yang kita butuhkan. Dalam praktiknya, tes beralih ke lapisan ini, itu diarahkan ke wadah kami, yang seharusnya membuat browser. Tapi dia tidak bisa menciptakannya, karena sumber daya habis. Oleh karena itu, tes masuk ke antrian, dan setelah 30 detik server proxy menjatuhkannya oleh batas waktu, karena secara default itu adalah interval waktu ini.

Bagaimana cara mengatasinya? Semuanya ternyata cukup sederhana - Anda hanya perlu mendefinisikan ulang haproxy.router.openshift.io/ anotasi timeout untuk perute wadah kami.
$oc annotate route moon --overwrite haproxy.router.openshift.io/timeout=10m
Kasing berikutnya bekerja dengan penyimpanan yang kompatibel S3. Moon dapat merekam apa yang terjadi dalam wadah dengan browser. Pada satu node, wadah layanan naik bersama dengan browser, salah satunya adalah perekam video. Ini merekam semua yang terjadi di wadah dan setelah akhir sesi mengirim data ke penyimpanan S3 yang kompatibel. Untuk mengirim data ke penyimpanan seperti itu, Anda perlu menentukan url, kata sandi partisipasi, dan nama keranjang dalam pengaturan.
Tampaknya semuanya sederhana. Kami memasukkan data dan mulai menjalankan tes, tetapi tidak ada file di repositori. Setelah menganalisis log, kami menyadari bahwa klien yang digunakan untuk berinteraksi dengan S3 bersumpah pada kurangnya sertifikat, karena di bidang url kami menentukan alamat untuk S3 dengan https. Solusinya adalah menentukan mode http yang tidak dilindungi atau menambahkan sertifikat Anda ke wadah. Opsi terakhir lebih sulit jika Anda tidak tahu apa yang ada di dalam wadah dan bagaimana semuanya bekerja.
Dan akhirnya ...
Setiap wadah browser dapat dikonfigurasi secara independen - semua parameter yang tersedia ada di dokumentasi Moon. Mari kita perhatikan pengaturan khusus seperti privilege dan nodeSelector.
Mereka dibutuhkan untuk ini. Wadah dengan Internet Explorer, seperti yang disebutkan di atas, seharusnya hanya berjalan dalam mode istimewa. Operasi dalam mode yang diperlukan disediakan oleh bendera istimewa bersama dengan penerbitan hak untuk meluncurkan kontainer tersebut ke akun layanan.
Untuk berjalan pada node yang terpisah, Anda harus mendaftarkan nodeSelector:
"internet explorer": { "default": "latest", "versions": { "latest": { "image": "docker-registry.default.svc:5000/ufs-selenoid-cluster/windows:7", "port": "4444", "path": "/wd/hub", "nodeSelector": { "kubernetes.io/hostname": "nirvana5.ca.sbrf.ru" }, "volumes": ["/var/lib/docker/selenoid:/image"], "privileged": true } } }
Kiat terakhir. Melacak jumlah sesi lari. Kami menampilkan semua peluncuran di Grafana:

Kemana kita pergi?
Kami tidak puas dengan semua yang ada di infrastruktur saat ini, dan solusinya belum dapat disebut lengkap. Dalam waktu dekat, kami berencana untuk menstabilkan IE di Docker, mendapatkan antarmuka UI "kaya" di Moon, dan juga menguji Appium untuk autotest seluler.