📱
Github Actions+AppiumでiPhone Simulatorを動かす
Github Actionsの環境にAppiumをインストールをしてiPhone Simulator上のSafariでブラウザの自動テストを実行する方法を共有します。
Github Actions仮想環境のインストール済みソフトウェア見てたらiPhone Simulatorインストール済みだったので普通にいけるのでは?と思いやってみたらできました。内容としてはAppiumをインストールしてSimulatorの制御とかはそちらに任せる感じです。
参考記事
ワークフロー定義
name: iPhone Simulator Test
on: [push, pull_request]
jobs:
build:
name: Safari Test
runs-on: macOS-10.14
steps:
- name: Checkout source code
uses: actions/checkout@v1
- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: '10.16.3'
- name: Set up Appium
run: npm install appium
- name: Run Appium Server
run: ./node_modules/.bin/appium --log-timestamp --log-no-colors > appium.log &
- name: Build with Gradle
run: gradle cleanTest test --tests "com.example.safari.MobileSafariTest"
continue-on-error: true
- name: Upload logs
uses: actions/upload-artifact@v1
with:
name: appium.log
path: appium.log
- name: Upload screenshots
uses: actions/upload-artifact@v1
with:
name: screenshots
path: screenshots
- Nodeをセットアップした後にnpmでAppiumをインストールします
-
./node_modules/.bin/appium > appium.log &
でログをあとで見れるように、またバックグラウンドプロセスになるようにしてAppiumサーバーを起動します、またログへのタイムスタンプ付加などのオプションを追加しています - JavaをセットアップしてGradleでテストを実行します
-
actions/upload-artifact
でスクリーンショットとログを保存します。保存したログ等はActionsの画面からダウンロードが可能です。
テストコード
コードはJava+JUnit5です。Qiitaにアクセスして文字入力して検索するだけですね。
@BeforeEach
void before() {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setBrowserName(BrowserType.SAFARI);
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST);
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone X");
caps.setCapability(MobileCapabilityType.PLATFORM_VERSION, "12.4");
caps.setCapability(MobileCapabilityType.LANGUAGE, "ja");
caps.setCapability(MobileCapabilityType.LOCALE, "ja_JP");
try {
driver = new IOSDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), caps);
} catch (MalformedURLException ign) {
// ignore
}
}
@AfterEach
void after() {
if (driver != null) {
driver.quit();
}
}
@Test
void testGet() {
driver.get("https://qiita.com/");
assertEquals("Qiita", driver.getTitle());
screenshot();
driver.get("https://qiita.com/search");
driver.findElement(By.id("q")).sendKeys("Selenium");
screenshot();
driver.findElement(By.className("searchResultContainer_searchButton")).click();
(new WebDriverWait(driver, 10)).until(ExpectedConditions.titleContains("Selenium"));
assertEquals("「Selenium」の検索結果 - Qiita", driver.getTitle());
screenshot();
}
まとめと課題
あんまり効率が良さそうには見えないのでキャッシュとかうまく効くようにしたいですね。WebDriverIOとか使ってJavaScriptでコード書けば全体はスッキリすると思います。
シミュレーターの定義はdeviceName
とplatformVersion
の組み合わせで決まるので、ここを環境変数から取得するようにすればマトリックスビルドにも対応できそう。
こんな感じです。AndroidもSDK入ってるしエミュレーター動かせそうな気はします(重そうだけど)。
Discussion