Mercari Engineering Blog

We're the software engineers behind Mercari. Check out our blog to see the tech that powers our marketplace.

AppiumのAIによる要素セレクタを試してみたら、自動テストの未来を感じた

初めまして。メルカリで自動化&品質保証グループ(Automation & QA Group:通称AQA)に8月からジョインし、自動化をぶりぶりしている@AHA_oretamaです。

10/18, 19にシカゴで開かれたSeleniumConf Chicagoに参加してきました。

SeleniumConf Chicagoの内容は@arminminさんの次回ブログを見てもらうとして、ここでは、その中で一番印象的だったセッションAI for element selectionで紹介されたTest.ai Classifier Plugin for Appiumプラグイン(以降、Test.ai Classifier Plugin)を使用したAIによる要素セレクタを試してみました。

(Test.ai Classifier Pluginの詳細については、そのセッション後すぐに、Appium:proでも紹介されましたので、気になる方はチェックしてください。また日本語にも翻訳してくれているので、こちらでもチェックできます。)

Test.ai Classifier Pluginの概要

Test.ai Classifier Pluginは、Test.aiが作っているAppiumの要素セレクタのプラグインで、OSSとして公開されています。Test.ai Classifier Pluginプラグインを使い、customタグにai:searchのように指定することで、AIが画面を認識して、要素を取得できるようになります。

実はAppiumはこのPRにより、サードパーティ製の独自セレクタをAppium driverに組み込むことができるようになっており、Test.ai Classifier Pluginもこの形式で提供されています。Appiumのサードパーティ製の独自セレクタについて、詳しくは以下を参考にしてください。

https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/element-finding-plugins.md

環境構築

試した自分の環境は以下になります。

  • OS: macOS High Sierra 10.13.6
  • Node: v10.11.0
  • npm: v6.4.1
  • ruby: v2.4.0

READMEに書いてありますが、いま現在(2018/10/23)、対応OSはMacのみとなっています。今後、Linux、Windowsともにサポートされるようです。

環境構築はREADMEに書いてある通りに行います。

まずはTest.ai Classifier Pluginに必要なパッケージをhomebrewでインストールします。homebrewが未インストールの方はここからインストールしてください。

$ brew install pkg-config cairo pango libpng jpeg giflib

サードパーティ製の要素セレクターはAppiumは1.9.2-beta.2以上でサポートされています。いま現在(2018/10/23)、1.9.2-beta.2より最新ものはないので、1.9.2-beta.2を指定してインストールします

$ npm install -g appium@1.9.2-beta.2

Test.ai Classifier Pluginをインストールする場所は、インストールしたAppiumのフォルダで行うほうがシンプルと書いてありましたので、今回はその通りに実行します。Appiumがインストールされたフォルダを調べてから、指定したフォルダに移動した後にインストールを行っています。

$ which appium
/Users/xxx/.anyenv/envs/ndenv/shims/appium
$ # anyenvを使用しているため実フォルダは以下になる
$ cd /Users/xxx/.anyenv/envs/ndenv/versions/v10.11.0/lib/node_modules/appium
$ npm install test-ai-classifier
> @tensorflow/tfjs-node@0.1.19 install /Users/xxx/.anyenv/envs/ndenv/versions/v10.11.0/lib/node_modules/appium/node_modules/@tensorflow/tfjs-node
> node scripts/install.js

* Downloading libtensorflow
[==============================] 990211/bps 99% 0.0s
* Building TensorFlow Node.js bindings
...

実際に試してみる

現状、使用可能なタグはlabels.jsに書かれています。タグ名だけではわかりにくければ、実際にAIの学習に使用している画像が公開されているので、こちらを見ればイメージがつかめると思います。

メルカリのアプリで使えそうなタグを調べててみると、cameracheck_markclosecredit_cardfavoritemenunotificationssharesearchなどなど非常に多くのタグが使えそうです。

ここでは、searchタグを使用して、AIによる検索アイコンの要素取得を行ってみたいと思います。メルカリのEndToEndテスト全体のソースは説明せず、Test.ai Classifier Pluginに関係するところのみ説明します。

ライブラリの対応

メルカリでは、AppiumによるEndToEndテストをRubyで作成しています。実際にメインで使用しているライブラリは、以下になります。

この中で、要素セレクタに関係するのはappium_libの依存関係に含まれているAppiumLibCoreと、appium_capybaraです。

appium_lib_coreはv2.0.4からサードパーティ製のプラグインを使用できるようになっています。ここでは最新にアップデートすることで対応します。

$ bundle update appium_lib_core

appium_capybaraはまだ対応がされていないようなので、selector.rbを作成し、spec_helper.rbで読み込みます。(これについては、PRを送ろうと考えています。そのPRがマージされた後のバージョンを使えば、以下の実装は不要になります。)
(2018/10/26 追記:appium_capybaraはPRが無事マージされ、v1.7.0以降を利用すれば以下の実装は不要になりました。)

support/extensions/selector.rb

Capybara.add_selector(:custom) do
  custom(:custom) { |locator| locator }
end

spec_helper.rb

# support files
SPEC_ROOT = __dir__
Dir[File.expand_path('support/**/*.rb', SPEC_ROOT)].each { |f| require f }

Desired Capabilitiesの追加

Test.ai Classifier Pluginを動かすためには、新しく追加されたcustomFindModulesshouldUseCompactResponsesをDesired Capabilitiesに追加する必要があります。

メルカリでは、appium_libのAppium.load_settingsを使用しているため、appium.txtに以下のように追加します。

appium.txt

[caps]
...
shouldUseCompactResponses = false

[caps.customFindModules]
ai = "test-ai-classifier"

spec_helper.rb

options = Appium.load_settings file: appium_txt, verbose: true

Capybara.register_driver(:appium) do |app|
  Appium::Capybara::Driver.new app, options
end

要素セレクタ部分の実装

メルカリではSitePrismを使用してPageObjectPatternを実装しているため、検索があるホーム画面は以下のような実装になります。SitePrismを使用せずに、driverのセレクタで書くと、search = driver.find_element(:custom,'ai:search')になります。

require 'site_prism'

module Pages
  class Home < SitePrism::Page
    element :search, :custom, 'ai:search'
  end
end

これをテストスクリプト側で呼び出します。(正確にはメルカリTurnipを使用しているので、step内実装されますが、ここでは無視しています。)

...
# ホーム画面までの遷移はこれより上に実装されている。
home = Pages::Home.new
home.search.click
# 検索以降の処理はこれより下に実装されている。
...

実際の動画

以下の動画は実際に上記の実装で行ったテストになります。ホーム画面の、ヘッダー部分に表示されている検索アイコンの押下はTest.ai Classifier Pluginによって要素取得されたものです。

他の要素の待ち処理もあるかと思いますが、若干、検索アイコンを押すまでに時間がかかっています。 0.8秒で認識できるとセッションでは言っていましたが、もう少しかかっている印象です。

AIによる要素セレクタのメリット / デメリット

AIによる選択はID、xpathなどのソースコードに依存しないため、細かい修正などによるID、xpathなどの変更の影響を受けず、保守性において非常にメリットがあると言えます。また、開発する際もID、xpathなどを調べずに済むため、開発効率も高そうです。

デメリットとして挙げられるのは、AI for element selectionのセッションでも話されてましたが、AIによる要素セレクターは100%の成功率ではない、ということです。AIを使用しているので、学習すればするほど100%に近づいていきますが、それでも100%にはなりません。(これはID、xpathなどのセレクタと比較して言っていると理解しました。正しいID、xpathなどのセレクタであれば100%要素を取得できますが、AIによる要素セレクタは誤認する可能性もある、ということだと思います。)

あとは動画でも見てもらった通り、要素セレクトまで若干の時間がかかります。パフォーマンスという観点では、ID、xpathなどのセレクタに軍配があがります。

所感

このようにAIによる要素セレクタがまだ試作段階ではありますが、もう使えるレベルまで来ています。AIが自動テストをする時代がすぐ近くに来ているということを肌で体感することができた、という意味でSeleniumConf Chicagoは非常に実りのあるカンファレンスになりました。

またAIによる要素セレクタを使うか、今まで通りのID, xpathなどでセレクタを使うか、という選択の幅ができたことで、今後はAI によるメリット・デメリット理解し、パフォーマンスや安定性を考慮しながら、どちらを使うか選択していくというスキルが求められるようになるのではないか、と思いました。

早くAIによる要素セレクタが実運用で使えるようになるといいですね。 自動テストの未来に期待がいっぱいです!