Herkese selam! Benim adım Taras Egorov; inDrive'da mühendisim. Size iOS ve Android cihazlarda günde 5.000'den fazla test çalıştırabilecek bir altyapıyı nasıl kurduğumuzu göstereceğim. İşin sırrı basit: Selenoid kullandık.
Geçtiğimiz yıl arkadaşlarımız oto test çalışması yaptılar, biz de çalışma kapsamında bir ankete katıldık.
Anketin bulgularından memnun kaldık, bu nedenle deneyimlerimizi sizlerle paylaşmak ve karşılığında tavsiye almak için bir makale yazmaya karar verdik. Materyali iki parçaya ayırmanın iyi bir fikir olduğunu düşündük: İlki Android'e, ikincisi ise iOS'a odaklanıyor.
Android'le başlayalım.
Selenoid, tarayıcıları ve Android öykünücülerini Docker kapsayıcısında çalıştırmak ve yönetmek için bir araçtır. Bu konuda daha fazlasını okuyabilirsiniz.
Appium testleri yazmak için şunları kullanırız:
browsers.json
yapılandırma dosyası oluşturun:
{ "android": { "default": "10.0", "versions": { "10.0": { "image": "browsers/android:10.0", "port": "4444", "path": "/wd/hub" } } } }
Emülatör görüntüsü image
dosyasında belirtilmiştir. adamlar Android emülatörlerinin hazır görsellerini hazırladılar. Bunları veya kontrol edebilirsiniz. Görseller birbirinden hiçbir şekilde farklı değildir.
Örnek olarak browsers/android:10.0
görselini ele alalım. Görüntünün önceden indirilmesi gerekir: docker pull browsers/android:10.0
, aksi takdirde testler çalışmaz:
Original error: create container: Error response from daemon: No such image: browsers/android:10.0
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$(pwd)/selenoid/config/":/etc/selenoid/:ro \ -p 4444:4444 \ --name selenoid \ aerokube/selenoid:1.10.7
Tarayıcınızdaki //localhost:4444 bağlantısını takip ederek Selenoid'in düzgün çalışıp çalışmadığını kontrol edebilirsiniz:
You are using Selenoid 1.10.7!
Sürücüdeki Appium testlerinde Selenoid adresini belirtin:
... val driver = AndroidDriver(URL("//localhost:4444/wd/hub"), capabilities) ...
... capabilities.setCapability("appium:app", "//storage.example.com/builds/app.apk") ...
Bağlantı sağlayamıyorsanız yapının yolunu belirtebilirsiniz:**
... capabilities.setCapability("appium:app", "/builds/app.apk") ...
Burada /builds/app.apk
öykünücünün çalıştırıldığı kabın içindeki yoldur. Bu seçeneğin düzgün çalışması için volumes
browsers.json
dosyasında belirttiğinizden emin olun:
{ "android": { "default": "10.0", "versions": { "10.0": { ... "volumes": [ "/home/username/app.apk:/builds/app.apk:ro" ] ... } } } }
Burada /home/username/app.apk
ana bilgisayar platformundaki yapıya giden yoldur.
İşte bu, neredeyse Selenoid'i kurduk ve şimdi testleri çalıştırmayı deneyebiliriz:
./mvnw test
Ancak ne yazık ki testler gerçekleştirilemeyecek. Hadi buna bakalım ve neyin yanlış olduğunu görelim.
Başarısız bir başlatmanın ardından yapılacak ilk şey Selenoid günlüklerini kontrol etmektir:
docker logs selenoid
[INIT] [Loading configuration files...] [INIT] [Loaded configuration from /etc/selenoid/browsers.json] [INIT] [Video Dir: /opt/selenoid/video] [INIT] [Your Docker API version is 1.41] [INIT] [Timezone: UTC] [INIT] [Listening on :4444] [NEW_REQUEST] [unknown] [172.17.0.1] [NEW_REQUEST_ACCEPTED] [unknown] [172.17.0.1] [LOCATING_SERVICE] [android] [10.0] [USING_DOCKER] [android] [10.0] [CREATING_CONTAINER] [selenoid/android:10.0] [STARTING_CONTAINER] [selenoid/android:10.0] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [CONTAINER_STARTED] [selenoid/android:10.0] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0.40s] [0] [REMOVING_CONTAINER] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0] [CONTAINER_REMOVED] [75e454341da7fc4b58ba104a5180813bac6cd7c124037a759b6c976e65b168fa] [0] [SERVICE_STARTUP_FAILED] [//172.17.0.3:4444/wd/hub does not respond in 30s]
Durumun SERVICE_STARTUP_FAILED olduğunu görüyoruz. gidin ve durum değerine bakın:
SERVICE_STARTUP_FAILED - Failed to start Docker container or driver binary
Hata size fazla bir şey söylemez ve daha fazla bilgi gereklidir. Konteyner kayıtlarına bir göz atmakta fayda var. Bunu günlüğe kaydetmeyi etkinleştirerek yapalım:
docker run -d \ -p 4444:4444 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$(pwd)/selenoid/config/":/etc/selenoid/:ro \ -v "$(pwd)/selenoid/logs/":/opt/selenoid/logs/ \ aerokube/selenoid:1.10.7 \ -log-output-dir /opt/selenoid/logs
Yetenekler bölümünde günlükleri de etkinleştiriyoruz:
... capabilities.setCapability("enableLog", true) ...
//localhost:4444/logs/ tarayıcısını kullanarak testleri çalıştırın ve günlükleri inceleyin:
2023-04-16T13:44:43.909768530Z Waiting X server... 2023-04-16T13:44:44.009494775Z Logging to: /tmp/fluxbox.log 2023-04-16T13:44:44.047587277Z Waiting X server... 2023-04-16T13:44:44.151933325Z Waiting X server... 2023-04-16T13:44:44.262850410Z * daemon not running; starting now at tcp:5037 2023-04-16T13:44:44.457972956Z * daemon started successfully 2023-04-16T13:44:44.458249266Z adb: no devices/emulators found 2023-04-16T13:44:45.463480812Z adb: no devices/emulators found 2023-04-16T13:44:46.471547723Z adb: no devices/emulators found 2023-04-16T13:44:47.476093515Z adb: no devices/emulators found 2023-04-16T13:44:48.481987351Z adb: no devices/emulators found 2023-04-16T13:44:49.486503149Z adb: no devices/emulators found 2023-04-16T13:44:50.492757801Z adb: no devices/emulators found 2023-04-16T13:44:51.499094108Z adb: no devices/emulators found 2023-04-16T13:44:52.505862428Z adb: no devices/emulators found 2023-04-16T13:44:53.513276412Z adb: no devices/emulators found 2023-04-16T13:44:54.520642210Z adb: no devices/emulators found 2023-04-16T13:44:55.527420189Z adb: no devices/emulators found 2023-04-16T13:44:56.534631013Z adb: no devices/emulators found 2023-04-16T13:44:57.316094939Z WARNING. Using fallback path for the emulator registration directory. 2023-04-16T13:44:57.335415397Z checkValid: hw configs not eq 2023-04-16T13:44:57.541959741Z adb: device offline 2023-04-16T13:44:58.547907700Z adb: device offline 2023-04-16T13:44:58.565504866Z emulator: WARNING: System image is writable 2023-04-16T13:44:58.565528396Z emulator: Cold boot: different AVD configuration 2023-04-16T13:44:58.565532576Z Your emulator is out of date, please update by launching Android Studio: 2023-04-16T13:44:58.565536346Z - Start Android Studio 2023-04-16T13:44:58.565539506Z - Select menu "Tools > Android > SDK Manager" 2023-04-16T13:44:58.565543076Z - Click "SDK Tools" tab 2023-04-16T13:44:58.565546216Z - Check "Android Emulator" checkbox 2023-04-16T13:44:58.565549216Z - Click "OK" 2023-04-16T13:44:58.565552146Z 2023-04-16T13:44:59.554451514Z adb: device offline 2023-04-16T13:45:00.560926060Z adb: device offline 2023-04-16T13:45:01.568777440Z adb: device offline 2023-04-16T13:45:12.124226047Z emulator: INFO: boot completed 2023-04-16T13:45:12.124251007Z emulator: INFO: boot time 27848 ms 2023-04-16T13:45:12.124255077Z emulator: Increasing screen off timeout, logcat buffer size to 2M. 2023-04-16T13:45:12.152557294Z emulator: Revoking microphone permissions for Google App.
Konteyner günlükleri de burada pek yardımcı olmuyor çünkü Appium günlüklerini göremiyorsunuz. Şimdi bunları etkinleştirmeye çalışalım. Bunu yapmak için, bakalım:
... if [ -z "$VERBOSE" ]; then APPIUM_ARGS="$APPIUM_ARGS --log-level error" else EMULATOR_ARGS="$EMULATOR_ARGS -verbose" fi ...
Appium günlüklerini etkinleştirmek için VERBOSE=true
ve APPIUM_ARGS=--log-level debug
: parametrelerinin konteynere iletilmesi gerekir:
{ "android": { "default": "10.0", "versions": { "10.0": { ... "env": [ "VERBOSE=true", "APPIUM_ARGS=--log-level debug" ] ... } } } }
Appium'un günlüklerde hata ayıklamasını sağlamak için VERBOSE'u iletmeniz gerekir; bu durumda emülatör günlükleri açılır ve "ether"i doldurmaya başlar” Ancak bunu gelecekteki görüntüler için düzelttik =)
Artık APPIUM_ARGS=-log-level debug
geçmek yeterli.
... [HTTP] --> POST /wd/hub/session/c89fa9c2-ca2b-49cd-ab31-590eeccf77d1/element [HTTP] {"using":"id","value":"authorization_edittext_phone"} [debug] [W3C (c89fa9c2)] Calling AppiumDriver.findElement() with args: ["id","authorization_edittext_phone"," c89fa9c2-ca2b-49cd-ab31-590eeccf77d1"] [debug] [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -and roid uiautomator [debug] [BaseDriver] Waiting up to 0 ms for condition [debug] [WD Proxy] Matched '/element' to command name 'findElement' [debug] [WD Proxy] Proxying [POST /element] to [POST //127.0.0.1:8200/wd/hub/session/65943f03-3b35-4d3eb221-d6dc7988f935/element] with body: {"strategy":"id","selector": "authorization_edittext_phone","context":"","multiple":false} [WD Proxy] Got response with status 404: {"sessionId":"65943f03-3b35-4d3e-b221-d6dc7988f935","value":{"error" :"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.El ementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(Find Element.java:73)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:41)\n\tat io.appium.uiautomator2.server.AppiumServlet. handleRequest(AppiumServlet.java:253)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:247)\n\tat io.appium.uiautomator2.http.Se rverHandler.channelRead(ServerHandler.java:68)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io .netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)\n\tat io.netty.chann... [debug] [W3C] Matched W3C error code 'no such element' to NoSuchElementError [debug] [W3C (c89fa9c2)] Encountered internal error running command: NoSuchElementError: An element could not be located on the page using the given search parameters. [debug] [W3C (c89fa9c2)] at AndroidUiautomator2Driver.findElOrEls (/opt/node_modules/appium/node_modules/appium-android-driver/lib/commands/find.js:75:11) [debug] [W3C (c89fa9c2)] at process._tickCallback (internal/process/next_tick.js:68:7) [HTTP] <-- POST /wd/hub/session/c89fa9c2-ca2b-49cd-ab31-590eeccf77d1/element 404 23 ms - 444 ...
Loglardan görüldüğü üzere Appium elementimizi bulamıyor. Emülatör ekranında neler olduğunu görelim. Bunu yapmak için Selenoid kullanıcı arayüzünü çalıştırmamız gerekiyor:
docker run -d \ --name selenoid-ui \ -p 8080:8080 \ --link selenoid:selenoid \ aerokube/selenoid-ui:1.10.4 \ --selenoid-uri "//selenoid:4444"
//0.0.0.0:8080 adresine gidin ve Selenoid kullanıcı arayüzünü açın:
Testlerde VNC ve video kaydını etkinleştirdiğinizden emin olun:
... capabilities.setCapability("enableVNC", true) capabilities.setCapability("enableVideo", true) ...
Selenoid başlatma komutu şu şekilde görünür:
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "(pwd)/selenoid/logs/":/opt/selenoid/logs/ \ -v /opt/selenoid/video/:/opt/selenoid/video/ \ -e OVERRIDE_VIDEO_OUTPUT_DIR="/opt/selenoid/video/" \ -p 4444:4444 \ -name selenoid \ aerokube/selenoid:1.10.7 \ -log-output-dir /opt/selenoid/logs
Testler başlatılıp çalıştırıldığında Selenoid kullanıcı arayüzünü açın:
Ve işte .
Başlatma hatasının nedenini bulduk. Harika! Hadi devam edelim.
Görünüşe göre Selenoid emülatörlerinin görüntüleri Google Play hizmetleri olmadan çalışmayacak. Bu durumu düzeltmek için kendiniz bir emülatör görüntüsü oluşturmalısınız. Aerokube'daki adamlar bunun için ihtiyacınız olan her şeyi bir araya getirdi: fotoğraflar ve .
selenium
klasörüne gidin../automate_android.sh
betiğini çalıştırın ve soruları yanıtlayın. Bizim durumumuzda şöyle görünüyor:
Specify Appium version: [1.18.1] >> 1.18.1 Specify Android image type (possible values: "default", "google_apis", "google_apis_playstore", "android-tv", "android-wear"): [default] >> google_apis Specify Application Binary Interface (possible values: "armeabi-v7a", "arm64-v8a", "x86", "x86_64"): [x86] >> x86 Specify Android version: [8.1] >> 10.0 Specify device preset name if needed (eg "Nexus 4"): >> Specify SD card size, Mb: [500] >> Specify userdata.img size, Mb: [500] >> Are you building a Chrome Mobile image (for mobile web testing): [n] >> y Specify Chromedriver version if needed (required for Chrome Mobile): >> 74.0.3729.6 Specify image tag: [selenoid/chrome-mobile:74.0] >> android-emulator:10.0 Add Android quick boot snapshot? [y] >> n
Android hızlı önyükleme anlık görüntüsü eklensin mi? sorusunu gördüğümde bunun bir emülatör olduğunu düşündüm. Ancak baktığınızda, APK uygulamalarını yüklemek için gereken bir çağırdığını görürsünüz. Temel olarak bize hiçbir kazanç sağlamaz.
anlık görüntü emülatörlerini zaten kullanıyoruz, ancak bunu diğer makalelerde konuşacağız.
İmaj oluşturulduktan sonra kayıt defterine aktarmamız istenecektir. Henüz buna ihtiyacımız olmadığından teklifi nazikçe reddedeceğiz:
Push? >> n
Google Play hizmetleriyle bir yapı oluşturduk. Tarayıcılar.json'daki görüntü parametresini değiştirmeyi ve Selenoid'i yeniden başlatmayı unutmayın.
Şimdi testleri tekrar çalıştırmayı deneyelim:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Ve .
Ne yaptık:
Size anlatmak istediğim başka bir şey daha var:
Bu arada bir sonraki bölümde altyapıyı nasıl büyüttüğümüzü ve iOS üzerinde testler yürüttüğümüzü anlatacağız.