【IaCで作るselenium環境】06_Androidコンテナを構築する(テスト実行編)
直近の関連エントリ
――――――――――――――――――――――――――――――――――
こんにちは。SHIFTのスクラムマスター・テスト自動化エンジニアの石丸です。
前回、Ansibleを使ってAzureVM上にAndroidコンテナを準備しました。
お待たせしました。
今回とうとうAndroidコンテナを動かすテストを実行してゆきます。
■今回のテーマ
今回のテーマは「Androidコンテナでのテスト実行」です。
いやー、ここに辿り着くまで結構長かった。。
■前提
・DockerDesktop Version 3.0.0(現時点での最新)
・windows環境での構築
・第5回までの内容が作業済みであること
■前回のおさらい
前回の最後はこんな感じでした。
AnsibleでVMにSelenoidが構築されています。
またAndroidコンテナも準備が整っています。
■テストコードの準備
実は第2回でAndroidのテストケースはaerokubeのGitHubから取得しているものの、一旦削除しています。
こちらを復活させます。DemoTestと同じフォルダに以下のソースコードを置きます。
AndroidDemoTest.java
テストコードの内容:電卓アプリを起動して、2+7を行う
package com.aerokube.selenoid;
import io.appium.java_client.MobileBy;
import io.appium.java_client.MobileElement;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import static com.aerokube.selenoid.DemoTest.takeScreenshot;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
public class AndroidDemoTest {
private static final By BUTTON_2 = MobileBy.xpath("//android.widget.Button[contains(@resource-id,'digit_2') and @text='2']");
private static final By BUTTON_PLUS = MobileBy.xpath("//android.widget.Button[@resource-id='com.android.calculator2:id/op_add']");
private static final By BUTTON_7 = MobileBy.xpath("//android.widget.Button[contains(@resource-id,'digit_7') and @text='7']");
private static final By BUTTON_EQUALS = MobileBy.xpath("//android.widget.Button[@resource-id='com.android.calculator2:id/eq']");
private static final By RESULT_FIELD = MobileBy.xpath("//android.widget.EditText[@resource-id='com.android.calculator2:id/formula']");
private RemoteWebDriver driver;
@Before
public void openDriver() throws Exception {
final DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "android");
device.setCapability("version", "8.1");
device.setCapability("appPackage", "com.android.calculator2");
device.setCapability("appActivity", "com.android.calculator2.Calculator");
device.setCapability("adbExecTimeout", "360000");
device.setCapability("androidInstallTimeout", "360000");
device.setCapability("skin", "WXGA720");
device.setCapability("enableVNC", true);
device.setCapability("enableVideo", true);
device.setCapability("enableLog", true);
driver = new RemoteWebDriver(new URL(
"http://test:test-password@172.17.0.1:8083/wd/hub"
), device);
}
@Test
public void browserTest() throws Exception {
try {
driver.findElement(BUTTON_2).click();
driver.findElement(BUTTON_PLUS).click();
driver.findElement(BUTTON_7).click();
driver.findElement(BUTTON_EQUALS).click();
} finally {
takeScreenshot(driver);
}
}
@After
public void closeDriver(){
if (driver != null){
driver.quit();
driver = null;
}
}
}
これとは別に第2回で準備したDemoTestの書き換えを行ってMobileChrome環境が起動するようにします。
書き換えるのは以下の部分です。
DemoTest.java
browser.setCapability("version", "mobile-75.0");
driver = new RemoteWebDriver(new URL(
"http://test:test-password@172.17.0.1:8083/wd/hub"
), browser);
バージョンとリモート先のURLだけ修正すればOKです!
またdemo-testフォルダ直下にあるpox.xmlのdependenciesに以下を追加します。
pom.xml
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.3.0</version>
</dependency>
■テスト実行!その前に
さて、あとはテスト実行するのみ!と行きたいですがまだ実行できません。
Ggrからルーティング設定と、VMのポート設定が出来ていませんね。
これをやります。
ポートの設定
Selenoidポートが未登録なのでこちらを開けます。
VMを選択し、メニューからネットワークを選びます。
受信ポートの規制一覧が表示されますので、画面左側にある「受信ポートの規制を追加する」を押します。
VM内に潜って確認。
Selenoidにforwordしているポートは8083です。
PS C:\WINDOWS\system32> ssh -i ~/.ssh/selenoidvm_key.pem azureuser@myselenoidvm.eastus.cloudapp.azure.com
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 5.4.0-1031-azure x86_64)
(中略)
azureuser@selenoidvmw:~$ sudo docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03e7707ed568 selenoid/video-recorder:latest-release "/entrypoint.sh" 2 hours ago Up About a minute (healthy) video-recorder
96bb3e328838 aerokube/selenoid:1.10.0 "/usr/bin/selenoid -…" 2 hours ago Up About a minute (healthy) 0.0.0.0:8083->4444/tcp selenoid
ですので8083ポートを許可します。
追加されました。
Ggrの設定
第2回で準備したGgrのtest.xmlに、AndroidとMobileChrome、AzureのDNS名を設定します。
test.xml
<qa:browsers xmlns:qa="urn:config.gridrouter.qatools.ru">
<browser name="firefox" defaultVersion="77.0">
<version number="77.0">
<region name="1">
<host name="172.17.0.1" port="4444" count="2" vnc="ws://172.17.0.1:4444/vnc" />
<host name="192.168.111.111" port="8447" count="2" vnc="ws://192.168.111.111:8447/vnc" />
</region>
</version>
</browser>
<browser name="chrome" defaultVersion="84.0">
<version number="83.0">
<region name="1">
<host name="172.17.0.1" port="4444" count="1" vnc="ws://172.17.0.1:4444/vnc" />
<host name="192.168.111.111" port="8447" count="2" vnc="ws://192.168.111.111:8447/vnc" />
</region>
</version>
<version number="84.0">
<region name="1">
<host name="172.17.0.1" port="4444" count="1" vnc="ws://172.17.0.1:4444/vnc" />
<host name="192.168.111.111" port="8447" count="2" vnc="ws://192.168.111.111:8447/vnc" />
</region>
</version>
<version number="mobile-75.0">
<region name="1">
<host name="myselenoidvm.eastus.cloudapp.azure.com" port="8083" count="1" vnc="ws://myselenoidvm.eastus.cloudapp.azure.com:8083/vnc" />
</region>
</version>
</browser>
<browser name="android" defaultVersion="8.1">
<version number="8.1">
<region name="1">
<host name="myselenoidvm.eastus.cloudapp.azure.com" port="8083" count="1" vnc="ws://myselenoidvm.eastus.cloudapp.azure.com:8083/vnc" />
</region>
</version>
</browser>
</qa:browsers>
test.xmlを修正したら、ローカルPCのGgrを再構築します。
PS C:\tmp\docker\ggr\ggr> docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
ggr /usr/bin/ggr -listen :4444 ... Up (healthy) 0.0.0.0:8083->4444/tcp
ggr-ui /usr/bin/ggr-ui -quota-dir ... Up (healthy) 0.0.0.0:8888->8888/tcp
selenoid-ui /selenoid-ui --selenoid-ur ... Up (healthy) 0.0.0.0:18080->8080/tcp
PS C:\tmp\docker\ggr\ggr> docker-compose down -v
Stopping selenoid-ui ... done Stopping ggr-ui ... done Stopping ggr ... done Removing selenoid-ui ... done Removing ggr-ui ... done Removing ggr ... done Removing network ggr_default
Removing volume ggr_ggr
Removing volume ggr_ggr-ui
PS C:\tmp\docker\ggr\ggr> docker-compose up -d --build --force-recreate
Creating network "ggr_default" with the default driver
Creating volume "ggr_ggr" with default driver
Creating volume "ggr_ggr-ui" with default driver
Building ggr
Step 1/7 : FROM aerokube/ggr:latest-release
---> aca0cf2239c9
Step 2/7 : MAINTAINER presales
---> Using cache
---> 23ee4cf49ce3
Step 3/7 : RUN set -x
---> Using cache
---> 1851e81d1464
Step 4/7 : RUN apk --update --no-cache --virtual build-dependencies add apache2-utils
---> Using cache
---> d383e8976df9
Step 5/7 : RUN mkdir -p /etc/grid-router/quota/
---> Using cache
---> 671ceab19d6b
Step 6/7 : COPY test.xml /etc/grid-router/quota/test.xml
---> 44b5c7f144e2
Step 7/7 : RUN htpasswd -bc /etc/grid-router/users.htpasswd test test-password
---> Running in b7ff54098813
Adding password for user test
Removing intermediate container b7ff54098813
---> afb217baaa4d
Successfully built afb217baaa4d
Successfully tagged aerokube/ggr:latest
Building ggr-ui
Step 1/5 : FROM aerokube/ggr-ui:latest-release
---> 0a5f4d02db09
Step 2/5 : MAINTAINER presales
---> Using cache
---> 6efc6694ed9e
Step 3/5 : RUN set -x
---> Using cache
---> 50cbda216a71
Step 4/5 : RUN mkdir -p /etc/grid-router/quota/
---> Using cache
---> af023ff1c900
Step 5/5 : COPY test.xml /etc/grid-router/quota/test.xml
---> eb89231371bb
Successfully built eb89231371bb
Successfully tagged aerokube/ggr-ui:latest
Creating ggr ... done
Creating ggr-ui ... done
Creating selenoid-ui ... done
Ggrの設定が有効になっているか確認します。
http://localhost:8083/quota
basic認証を聞かれるので入力します。
読み込まれていますね。
Ggr-UI(Selenoid-UI)も確認します。
http://localhost:18080/#/
quotaの数も増え、selenoid-UIもListen出来ているようです。
■今度こそテスト実行!
テストを起動します。
第2回で準備したmavenコンテナを再実行します。
修正したテストコードを格納しているフォルダ「demo-test」直下で以下のコマンドを打ちます。
PS C:\tmp\docker\mvn> docker run -it --net="bridge" --name demo-test -v ${PWD}/demo-tests:/usr/src/mymaven -w /usr/src/mymaven maven mvn clean install test
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.aerokube.selenoid:demo-test:jar:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-source-plugin is missing. @ line 42, column 21
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------< com.aerokube.selenoid:demo-test >-------------------
[INFO] Building demo-test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
(中略)
[INFO] Installing /usr/src/mymaven/target/demo-test-1.0-SNAPSHOT.jar to /root/.m2/repository/com/aerokube/selenoid/demo-test/1.0-SNAPSHOT/demo-test-1.0-SNAPSHOT.jar
[INFO] Installing /usr/src/mymaven/pom.xml to /root/.m2/repository/com/aerokube/selenoid/demo-test/1.0-SNAPSHOT/demo-test-1.0-SNAPSHOT.pom
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo-test ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /usr/src/mymaven/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ demo-test ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo-test ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ demo-test ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo-test ---
[INFO] Skipping execution of surefire because it has already been run for this configuration
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:15 min
[INFO] Finished at: 2020-12-15T16:34:05Z
[INFO] ------------------------------------------------------------------------
こんな感じでテストが正常終了します。
ちなみに実行中はコンテナ内でエミュレータ、ADB、Appiumの処理を行っているため、起動にちょっと時間がかかかります。
なお実行中にVMに潜ってdocker container ls -aするとAndroidコンテナの起動しているのがわかりますので、logsコマンドで中身を出力すると実行の様子も確認できます。
azureuser@selenoidvm:~$ sudo docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5765825e9172 selenoid/video-recorder:latest-release "/entrypoint.sh" 56 seconds ago Up 55 seconds wizardly_burnell
c2dd67145a4c selenoid/android:8.1 "/entrypoint.sh" 57 seconds ago Up 55 seconds 4444/tcp, 5900/tcp, 7070/tcp, 8080/tcp, 9090/tcp loving_mccarthy
03e7707ed568 selenoid/video-recorder:latest-release "/entrypoint.sh" 3 hours ago Up 17 minutes (healthy) video-recorder
96bb3e328838 aerokube/selenoid:1.10.0 "/usr/bin/selenoid -…" 3 hours ago Up 43 minutes (healthy) 0.0.0.0:8083->4444/tcp selenoid
azureuser@selenoidvm:~$ sudo docker container logs -f loving_mccarthy
Waiting X server...
Waiting X server...
Waiting X server...
Waiting X server...
Logging to: /tmp/fluxbox.log
Waiting X server...
Waiting X server...
Waiting X server...
* daemon not running; starting now at tcp:5037
(以下略)
暫くしてselenoiu-UIで起動が確認できます。
android8.1起動
mobile chrome起動
■動作確認
Ggrから複数のSelenoidへ接続するため、第1回のときのようにvideoフォルダが(特定)表示できません。
今回はscpコマンドでVMにアクセスし、videoをダウンロードしてきます。
PS C:\tmp\docker\mvn> scp -i ~/.ssh/selenoidvm_key.pem azureuser@myselenoidvm.eastus.cloudapp.azure.com:/usr/local/selenoid/video/* c:\tmp\docker\mvn\
androidの動作
再生してみます。
2+7の計算が確認できます。
mobileChromeの動作
同じく再生してみます。
第1回と同じ動作がAndroid上のChromeで実行されることが確認できます。
今回作成された構成
■SelenoidのAndroidコンテナに対する率直な感想
ここまで組んでおいてアレですが、実際に動かした感想として遅かったり不安定だったりと、現時点では実用に耐えうるものではないかなーという印象です。
ただAerokubeのissueを見ると結構海外では実績があるようで。。
VMに割り当てたリソースがしょぼいからか、私の構築がイケてないからか。。引き続き検証していこうと思います。
■まとめ
実際の構築手順
1. AndroidとMobileChromeテストコードの準備をする
2. pom.xmlを修正する
3. AzureVMのSelenoidポートを開ける
4. Ggrのtest.xmlを修正して起動ルートを作る
5. Ggrコンテナを再構築する
6. テストを起動する(第2回で準備したコンテナの実行)
==================================================
不安定ではありましたが、Selenoidを使用してAndroidコンテナにてテストを実行することができました。
さて、ここまでの手順でいささか面倒だったのは第4回のVM準備です。
GUIでポチポチ操作はやっぱり手間ですよね。
ということで次回はこれをTerraformを使用してコマンド一発(正確には3発ぐらい)で構築できるようします。
ではでは。
――――――――――――――――――――――――――――――――――
【ご案内】
テスト自動化のご相談は以下までお気軽にご連絡ください。
https://forms.office.com/Pages/ResponsePage.aspx?id=IkyjGtUOzUeqMMEbzjGdlSf__O4V1URMn-5BpGP8xd9UNE9ESkRPUEs1Wk9FM0REU1BXODFBSkI0MC4u
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/