iOS
appium

Appium1.6.xでAppium再入門

More than 1 year has passed since last update.

「実践Appium」出ましたね、Appium好きなのでAppiumオンリーの本が出たのは個人的にテンション上がります。
しかし書籍の中のAppiumは1.6.0以前のUIAutomationを使ってるものとなってるようです。

iOS10でUIAutomationがdeprecatedになり、Appiumもそれに伴い1.6.0でXCUITestをベースとした形に移行したようで、UIAutomationの代わりにFacebook製のWebDriverAgentになったようです(それについての詳細も今後書けたらいいなと思ってます)

そんなわけで今回は久々にAppiumを動かしてみました。

公式のリポジトリのサンプルコードが実行できるようになるまでの手順と
途中でハマった箇所とその解決方法を載せておきます。

appiumとは?

すでにQiitaに良い記事が書かれてるので割愛します。
http://qiita.com/k5n/items/899cf40a0021a6a92efd

環境構築

公式の通りやっていけば特に問題はないと思います。
この記事ではnodeはnodebrewv6.6.0を使っています。
https://github.com/appium/appium

一応コマンドも書いておきます。

npm -g install appium
npm -g install appium-doctor

今回使ったappiumのバージョンは1.6.2です。

appium-doctor

appium-doctorで現在の環境のチェックをし、何か足りないものがあればインストールなりを行ってください。

私の手元で実行するとこんな感じでした。

info AppiumDoctor Appium Doctor v.1.2.5
info AppiumDoctor ### Diagnostic starting ###
info AppiumDoctor  ✔ Xcode is installed at: /Applications/Xcode.app/Contents/Developer/
info AppiumDoctor  ✔ Xcode Command Line Tools are installed.
info AppiumDoctor  ✔ DevToolsSecurity is enabled.
info AppiumDoctor  ✔ The Authorization DB is set up properly.
info AppiumDoctor  ✔ The Node.js binary was found at: /usr/local/bin/node
info AppiumDoctor  ✔ Carthage was found at: /usr/local/bin/carthage
info AppiumDoctor  ✔ HOME is set to: $HOME
WARN AppiumDoctor  ✖ ANDROID_HOME is set to '$HOME/android-sdks' but this is NOT a valid path!
info AppiumDoctor  ✔ JAVA_HOME is set to: /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home
WARN AppiumDoctor  ✖ adb could NOT be found at '$HOME/android-sdks/platform-tools/adb'!
WARN AppiumDoctor  ✖ android could NOT be found at '$HOME/android-sdks/tools/android'!
WARN AppiumDoctor  ✖ emulator could NOT be found at '$HOME/android-sdks/tools/emulator'!
WARN AppiumDoctor  ✖ Bin directory for $JAVA_HOME is not set
info AppiumDoctor ### Diagnostic completed, 5 fixes needed. ###
info AppiumDoctor 
info AppiumDoctor ### Manual Fixes Needed ###
info AppiumDoctor The configuration cannot be automatically fixed, please do the following first:
WARN AppiumDoctor - Manually configure ANDROID_HOME.
WARN AppiumDoctor - Manually install adb and add it to PATH.
WARN AppiumDoctor - Manually install android and add it to PATH.
WARN AppiumDoctor - Manually install emulator and add it to PATH.
WARN AppiumDoctor - Add '$JAVA_HOME/bin' to your PATH environment
info AppiumDoctor ###
info AppiumDoctor 
info AppiumDoctor Bye, run appium-doctor again when all manual fixes have been applied!
info AppiumDoctor 

Androidについての設定でxが付いてますがiOSだけ動かすのでこれでOKです。

サンプルコード

今回は以下のappiumのリポジトリにあるサンプルコードを使用します。
https://github.com/appium/sample-code

適当なところにgit clone https://github.com/appium/sample-codeしませう。

内容は以下のような構成になってます。

sample-code/
├── apps <- サンプルで動かすテストコード集
│   ├── ApiDemos
│   ├── ContactManager
│   ├── RobotCalibration
│   ├── RottenTomatoes.zip
│   ├── RottenTomatoesPageSnapshot.html
│   ├── RottenTomatoesSnapshot.html
│   ├── TestApp
│   ├── ToggleTest
│   ├── UICatalog.zip
│   ├── WebViewApp
│   ├── android-rottentomatoes-demo-debug.apk
│   ├── chromedriver
│   ├── chromedriverWin
│   └── selendroid-test-app.apk
└── examples <- 各言語毎のサンプルコード集
    ├── C#
    ├── RobotFramework
    ├── dotnet
    ├── java
    ├── node
    ├── perl
    ├── php
    ├── python
    └── ruby <- 今回はコレで遊ぶ

rubyのサンプルを動かす

cd sample-code/sample-code/examples/rubyでrubyのサンプルプログラムに移動しましょう。
次にrubyのテストをするための各種gemをインストールします。

その前にちょっとGemfileを確認。

source 'https://www.rubygems.org'

gem 'appium_lib',         '~> 6.0.0' <- サンプルの場合appium_libのバージョンが古いみたい
gem 'rest-client',        '~> 1.6.7'
gem 'rspec',              '~> 2.14.1'
gem 'cucumber',           '~> 1.3.15'
gem 'rspec-expectations', '~> 2.14.5'
gem 'spec',               '~> 5.3.4'
gem 'sauce_whisk',        '~> 0.0.13'
gem 'test-unit',          '~> 2.5.5' # required for bundle exec ruby xunit_android.rb

appium_libのバージョンが古いので上げておきましょう。

source 'https://www.rubygems.org'

gem 'appium_lib',         '~> 9.0.0'
gem 'rest-client',        '~> 1.6.7'
gem 'rspec',              '~> 2.14.1'
gem 'cucumber',           '~> 1.3.15'
gem 'rspec-expectations', '~> 2.14.5'
gem 'spec',               '~> 5.3.4'
gem 'sauce_whisk',        '~> 0.0.13'
gem 'test-unit',          '~> 2.5.5' # required for bundle exec ruby xunit_android.rb

改めてインストール実行です。

bundle install

※rubyのバージョン管理についてはrbenv2.3.3p222を使いました。bundlerrbenvのインストール方法はここでは割愛します。

今回はrspecはすっ飛ばしてcucumberで遊びます。

Desired Capabilities

実行の前にCapabilityの設定も確認して見ましょう。

cd ./cucumber_ios/features/support/iphonesim

ここには後述する実行時に与えるcapabilitiesのための設定ファイルが配置されています。
appium.txtというファイルがあると思うので中身を確認してみましょう。

注意⚠️ appium.txt./cucumber_ios/features/support/直下にもあります。後述するcucumberの実行時のパラメタを指定しない場合は./cucumber_ios/features/support/appium.txtの値が採用されます。

.
├── appium.txt
├── env.rb
├── ipadsim
│   └── appium.txt
└── iphonesim
    └── appium.txt <- 今回見るのはこっちね。

ファイルの中身はtoml形式(https://github.com/toml-lang/toml) で各種キーとその値が定義されています。

では確認してみましょう。

[caps]
platformName = "ios"
deviceName = "iPhone 6"
platformVersion = "8.1"
app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp.app"

[appium_lib]
sauce_username = false
sauce_access_key = false

私の実行環境に合わせてちょっと変更します。

[caps]
platformName = "ios"
deviceName = "iPhone 6"
platformVersion = "10.1" <- 8.1 -> 10.1にしただけ
app = "../../../apps/TestApp/build/release-iphonesimulator/TestApp.app"

[appium_lib]
sauce_username = false
sauce_access_key = false

platformVersionを10.1に変更しました。※後述するトラブルシューティングのエラーが出たため。

この他にもDesired Capabilitiesには色々な設定が定義されていますので一度確認しておくと良いでしょう。
Desired Capabilitiesは
http://appium.io/slate/en/master/?ruby#the-default-capabilities-flag
または
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md
で確認できます。

cucumberでの実行

sample-code/sample-code/examples/ruby/cucumber_ios/に戻って以下のコマンドを実行します。

bundle exec cucumber -p iphonesim
...
...

2 scenarios (2 passed)
8 steps (8 passed)
4m25.116s

無事実行完了です🎉

トラブルシューティング集

今回のサンプルを動かす上でで引っかかった時に出たエラーメッセージとその解決方法です。

Appium's IosDriver does not support xcode version 8.1. Apple has deprecated UIAutomation. Use the "XCUITest" automationName capability instead.

capabilitiesにautomationName = "XCUITest"を追加しましょう。
上記の方法でもよかったのですがappium_libのバージョン9.0.0からデフォルトがXCUITestになったようで、不要となりました。

Platform version must be 9.3 or above. '8.1' is not supported

capabilitiesのplatformVersionの値を変更しましょう。

Do you want the application “WebDriverAgentRunner-Runner.app” to accept incoming network connections?

iOS側ではなく、MacOSでアプリが通信する際に出るアラートでこれが出る場合がありました。
初回起動時だけかと思ったのですが、毎回このアラートが出てしまいました。
このダイアログはMacOSのfirewallがOnになってると出るため、

一時的なとしてfirewallをOffにすると当然出なくなりました。誰かもっといい方法あれば教えてください。
※firewallがOnでアラートが出てもテストは問題なく完了するので放置でもいいかな。

May Slow Down Your iPhone

サンプルのアプリが32bitでビルドしたものを実行してるためです。再ビルドしましょう。
samples/sample-code/sample-code/apps/TestAppで以下のコマンドを実行します。
64bitでのビルドのため-arch x86_64が必要となります。

xcodebuild -sdk iphonesimulator -arch x86_64

要素の特定

テストを書いて実行するとうまく要素が取れない場合などがあります。
そのような場合はappium-consoleを使ってインタラクティブに自分が欲しい要素の特定方法を探る事ができます。

appium-console

使い方は以下参照
http://appium.io/slate/en/tutorial/ios.html?ruby#starting-the-console

appium-consoleはインストールするとarcコマンドが使えるようになります。
サンプルにsample-code/sample-code/examples/ruby/arc_ios_calcがあるのでこれで動かしてみましょう。
sample-code/sample-code/examples/ruby/arc_ios_calc/appium.txtにCapabilityについてのファイルがあります。前述したCapabilityの設定に修正してください。

次に設定ファイルに移動します。

cd sample-code/sample-code/examples/ruby/arc_ios_calc

次にarcコマンドを実行します。

arc

capabilityファイルが複数ある場合などは以下のように
tomlファイルを指定しましょう;

arc toml appium.txt

無事起動できたらコマンドを実行して色々と試してみましょう。

page

pageコマンドで表示されている画面の要素の一覧を見ることが出来ます。

$page
XCUIElementTypeApplication
   name, label: TestApp
   value: 
   hint: 
XCUIElementTypeOther
   name, label, value: 
   hint: 
...
省略
...
XCUIElementTypeOther
   name, label: -100% battery power
   value: 
   hint: 
nil

page_class

page_classを実行するとページを構成するクラスとその数を表示します。

$page_class
7x XCUIElementTypeButton
6x XCUIElementTypeOther
5x XCUIElementTypeStaticText
2x XCUIElementTypeTextField
2x XCUIElementTypeWindow
1x XCUIElementTypeStatusBar
1x XCUIElementTypeSwitch
1x XCUIElementTypeSlider
1x XCUIElementTypeApplication
nil

その他のコマンド

以下参照 
https://github.com/appium/ruby_lib/blob/master/docs/ios_docs.md

textfieldsbuttonsなどがよく使うのではないかと思います。

終わりに

久々にAppiumを触ってみた感想としては環境構築の部分はアップデートしないとダメでしたが、
テストコード自体は全く変更せずにサンプルを動かすことが出来ました。
UIAutomationのコードとXCUITestのコードでは文法も言語も異なるため、
Appiumがこうした差異を吸収してくれるのは嬉しいですね。
その反面Appium自体の学習コストなどもありますが、それについては今後別に検証・検討したいと思います。

参考URL

正直こっちの方がすごく良い記事ですね...。
http://qiita.com/k5n/items/899cf40a0021a6a92efd
http://qiita.com/k5n/items/6e81b5986361bd1e3cd0
http://qiita.com/k5n/items/086af8fe16af2924aaa8