[Appium][Android]Set DataPicker and TimePicker via Espresso Driver

Selenium/Appium Advent Calendar 2018、17日目の記事です。空いていたので、ちょっとしたtipsということでAppiumの mobile command を紹介しようと思います。(English edition is available in [Appium][Android]Set DataPicker and TimePicker via Espresso Driver (Eng))

AppiumはW3Cに沿った基本的なコマンドのほか、iOS/Androidなどに特化したコマンドを拡張しやすくするために mobile command を定義しています。これは、例えばW3Cの定義には当てはまらない上に、AndroidやiOS固有の機能を拡張するためによく使っています。

従来の機能追加の方法としては、各種コマンドは全て何らかのURIにマッピングされていました。 ただ、特定のDriverでしか使うことはないのに必要以上にURIを乱立させたくはありません。保守が難しくなってきます。

そのため、 mobile: というprefixをつけたコマンドを文字列で定義し、このように各々の固有な機能を定義するようにしました。Androidだと adb コマンド、iOSだと siri の機能を使ったコマンドなどが拡張されています。

ここでは、それらで定義されたAndroidの2つのコマンドを紹介しようと思います。

DatePickerとTimePicker

最近ではAndroidだとDatePicker, TimePicker, 任意のpublic method を呼び出すことができる backdoor などの機能が追加されました。

これらの機能は、Appium 1.10.0 などで automationName: espressoと指定すると利用可能な、 Espresso Driver に追加されたmobile commandです。技術的にはEspressoベースだからできるようになったことです。

これらは今まではuiautmaotor経由だったためにできなかった/不安定だったところを解消する可能性が高いです。

テストコード

先ほど埋め込んでいたanimation gifは、すでにruby_lib_coreに用意している以下のテストコードを動かしている時のものです。実際に mobile: setDatemobile: setTime を使い値を設定している例になります。

少しコードを追ってみると、mobile: setDatemobile: setTime を使い値を設定していることがわかります。それらの要素をfind_elementからの.textなどで取得すると、確かに設定が変わっている(上のアニメーションも合わせるとアニメーションからも何となくわかるかと思います)ことが見えると思います。

# Ruby
def test_datepicker
  caps = Caps.android 'io.appium.android.apis.view.DateWidgets1'
  @core = ::Appium::Core.for(caps)
  @driver = @core.start_driver

  @driver.find_element(:accessibility_id, 'change the date').click

  date_picker = @driver.find_element(:id, 'android:id/datePicker')
  @driver.execute_script('mobile: setDate', { year: 2020, monthOfYear: 10, dayOfMonth: 25, element: date_picker.ref })
  assert_equal 'Sun, Oct 25', @driver.find_element(:id, 'android:id/date_picker_header_date').text
end

# @since Appium 1.11.0 (Newer than 1.10.0)
def test_timepicker
  caps = Caps.android 'io.appium.android.apis.view.DateWidgets2'
  @core = ::Appium::Core.for(caps)
  @driver = @core.start_driver

  time_el = @driver.find_element(:class, 'android.widget.TimePicker')
  @driver.execute_script('mobile: setTime', { hours: 11, minutes: 0, element: time_el.ref })
  assert @driver.find_element(:id, 'io.appium.android.apis:id/dateDisplay').text == '11:00'

  time_el = @driver.find_element(:class, 'android.widget.TimePicker')
  @driver.execute_script('mobile: setTime', { hours: 15, minutes: 15, element: time_el.ref })
  assert @driver.find_element(:id, 'io.appium.android.apis:id/dateDisplay').text == '15:15'
end

締め

簡単ですが、mobileコマンドを利用する方法を紹介しました。

今後もEspresso、XCUITestなどに関しても特定の機能に特化したAPIが生まれる事かと思います。それらの多くはこのようにAppiumを拡張する事でも利用可能になります。また、一部のサービスではさらに拡張して実音声を使ったSiriの自動化などもサポートするといったところまであります。様々な性能計測も含めて。

単なる機能的な確認として組み込むだけではなく、開発しているサービス/製品の機能性以外のところまで自動化してシナリオに落とし込むこみ、数値を継続して取得、製品に対する品質を継続して観察できるようになるといろんな判断にも役立てることができそうですね。

1 Comment

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.