Appium1.0.0(Orion)とruby_libを使ってみる

Appium 1.0.0 がリリースされていましたね。Orionという名前っぽい。

これからruby_libなどのライブラリがappium側の正式サポートとして整備されていくわけですが、0.18.x系から1.0.0系はappiumとしての機能が追加されていく、と開発者の方はGithub上でちょくちょくいっています。そこで、0.18.x系と1.0.x系で変わったところの確認と、ruby_libを軽く使ってみての内容を以下に書いてみます。

ruby_libのようなラッパーライブラリ使うと、多くは不具合発生時の原因特定が難しいのですが、ruby_libをざっと見ていると、基本的な機能の多くは単に@driver.xxxをラップしているだけで、必要な箇所はさらに拡張を施しているなので、そこはあまり深く考えなくてよさそう。ruby_libは直接appiumのruby bindingも利用可能なので、おそらく起動スクリプト以外は大きく変わらないでしょうので使わない理由は特に今のところ見当たらない。なので、実務でもちょくちょく置き換えていこうと思います。

execute_script
find_element
find_elements

ruby_libの導入

ruby_libは、以下のgithub上で開発が行われています。
https://github.com/appium/ruby_lib

導入の方法はreadmeに記載されているので省略。

appium_libを使ってdriverの起動

以下のような構文を使うことで、driverを起動させます。

desired_capabilities = {
    platformName: :ios,
    platformVersion: '7.1',
    deviceName: 'iPhone Retina (4-inch)',
    app: APP_PATH_IOS,
    raw: APPIUM_CAPABILITIES_IOS
}

server_caps = {
  server_url: custom_server,
  wait: 20, #min
  debug: true
}

caps = { caps: desired_capabilities, appium_lib: server_caps }

Appium::Driver.new(caps).start_driver

Appium.promote_appium_methods Object

desired_capabilitiesには、今までのappiumのcapabilityです。
内容の詳しくは以下を参照のこと。
https://github.com/appium/appium/blob/master/docs/en/caps.md

ruby_libでは、rawでいくつかの要素を追加できる記述があります。
これでraw指定の箇所は動的に要素を変更しながら、スクリプトを回すこともできますね。
ただし、コードを見る限りはrawである必要もなさそうなので、んー?という感じですが。

要素指定で、ruby_libを指定していると、その要素では以下を指定できるみたい。

appium_lib: server_caps

で指定している所は、以下を指定できるようです。

# appium_lib specific values
@custom_url       = appium_lib_opts.fetch :server_url, false
@export_session   = appium_lib_opts.fetch :export_session, false
@default_wait     = appium_lib_opts.fetch :wait, 30
@last_waits       = [@default_wait]
@sauce_username   = appium_lib_opts.fetch :sauce_username, ENV['SAUCE_USERNAME']
@sauce_access_key = appium_lib_opts.fetch :sauce_access_key, ENV['SAUCE_ACCESS_KEY']
@port             = appium_lib_opts.fetch :port, 4723
@debug

customer_urlは、defaultではhttp://127.0.0.1:#{@port}/wd/hubのようなので、例えばAppium serverを特定のURL/port指定して起動させ、そこに対して通信を確立させたい場合はちゃんと引数から指定してあげる必要がありますね。

Appium.promote_appium_methods Object

を最後に宣言することで、Objectすべてにappiumのメソッドすべてを適用できるようです。
これがないと、Appium::Driver...や、$driverのようにグローバルにruby_libにより定義されるメソッドすべてを利用しないといけないです。これは面倒だし、ruby_libを使わないときとの記述差が大きくなるので、メソッド名の衝突がない限りは使わない理由はないかもしれないですね。

Appium 1.0.0

https://github.com/appium/appium/blob/master/docs/en/migrating-to-1-0.md
で主な変更点を確認できるのですが、気になったとこを少し。

0.18.0の頃から、xpathの仕様を変更するといっていたのですが、1.0.0からその宣言通りデフォルト設定がかわりました。

find_element(:xpath, '//window[1]/navigationbar[1]/button[1]')

が、

find_element(:xpath, '//UIAApplication[1]/UIAWindow[1]/UIANavigationBar[1]/UIAButton[1]')

のようになります。これは書き換えが少し面倒なのですが、iOSの実装時の表現により近づいたので、実は使いやすくなったのかなと思います。

mobile:メソッドの幾つかが使えなくなってますね。ruby_libでは、tapなどは中身を見るとmulti_touchで書き直されていますので、直接appium操作する時もそれに習えばよいのかなと。

注意

今のところUIASecureTextFieldの要素を取得できない?ように見えるため、パスワード入力がsend_keysによりできなかったりと、0.18.2では動く箇所が動かなかったりと十分に使えない。。。
ログを見ていると、これらはxpathのvalueの指定先がマルチバイト文字だとうまくElementを取得できないようにもみえるので、UIASecureTextFieldだからというわけではなさそう。
※UIASecureTextFieldは悪くない、との断定までできていないのでこのような表現です・・・

value = 'マルチバイト文字'
find_element(:xpath, "//*[@value=#{value}]").send_keys text

GUIツール

AppiumのGUIツールが使いやすくなっていました。一番の驚きかも。
Record機能は使ってないのですが、そちらも発展しているようなら、実装に比重を置いていないエンジニアの方々も操作できるのかも?(Selenium IEDのように)

最後に

特定のアカウントでログインするというシナリオを実施する場合、xpathの症状ではどうしようもないので、0.18.2を主に使いつつ、1.0.0に変更可能な粒度でメソッドのメンテナンスを行おうと思います。もう少し調べて、原因が分かればPRでも出してみたいなと思う最近です。

とりあえず、Appiumのような自動化ツールは開発を補佐する上でも大切(画面網羅のスクリーンショットを撮ってくれるだけでもかなり作業を楽にしてくれる)なので、継続しておっていく予定。

追記(20140615)

find_elementのname strategyがaccessibility_id strategyにスイッチしましたね。
以下のように書き換えるとその対応が行えます。

  • 変更前
    @driver.find_element(name: element_name)
  • 変更後
    @driver.find_element(accessibility_id: element_name)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中