読者です 読者をやめる 読者になる 読者になる

sumioの技術メモ

Androidについての記事が多くなると思います。

Android Testing Bootcamp #1で、Appiumの適用事例について発表しました #Android_Testing_BC

Android Appium

2016年3月23日(水)に開催された、Android Testing Bootcamp #1で、「受託開発プロジェクトでAppiumによるテスト自動化を試す」というタイトルで発表しました。以下が発表資料です。

続きを読む

DroidKaigi 2016で、UI Automator2について講演しました #DroidKaigi

2016/2/18(水)-19(木)に開催された、DroidKaigi 2016で「生まれ変わったUI Automatorを使いこなす」というタイトルで講演しました。以下が講演資料です。

続きを読む

Roppongi.aar #2で、UI Automator 2について発表しました #roppongi_aar

2015/11/17(火)に開催された、Roppongi.aar #2で「UI Automator Becomes Friendly with Espresso」というタイトルで発表してきました。以下が発表資料です。

新しくなったUI Automator 2では、Espressoと混ぜて使うことができる、という内容です。

Espressoを使ったテストを書いている時に、連携先のアプリを操作したくなることがあると思います。 そういうときに、連携先のアプリに遷移したところだけUI AutomatorAPIを使ってテストを書くことができるのです。

新しいUI AutomatorAndroid Instrumentation Testをベースに書き直されたことによって、このようなことが可能になりました。

具体的な動作例はGitHubにアップロードしましたので、参照してみてください。

UI Automator 2の仕組みについて

ところで、Android Instrumentation Testは、テストコードと同一の開発者署名が施されたアプリケーションしか操作できなかったはずです。 それにもかかわらず、UI Automatorは、異なる署名のアプリを操作できています。これは、どのような経緯によるものなのでしょうか。

UI Automator 2のソースコードを辿っていくと、最終的にInstrumentationUiAutomatorBridgeというクラスからUiAutomationを参照していることが分かります。

このUiAutomationクラスのインスタンスInstrumentation.getUiAutomation()から取得することができますので、Instrumentation Testから呼び出すことができるのです。

UI Automator 2は、UiAutomationが提供しているメソッドを駆使して第三者が署名したアプリの操作を実現している、ということになります。これらのAPIの利用には、特殊な権限はいりません。

アクセシビリティまわりのAPI構造を理解していないとなかなか使いこなすのが難しそうですが、これらのAPIを駆使すればUI Automatorの気に入らない部分だけ自作したり、あるいは新しいテストフレームワーク全体を作ることもできるはずで、色々と夢は広がります!

最後に

今回の勉強会は「英語推奨」ということで、スライドだけはなんとか英語にして本番に臨んだのですが、 喋りについては日本語で発表させていただきました。 海外の参加者も何人かいらっしゃったので、発表も英語でできれば良かったのですが、そこまでは手が回りませんでした。 また発表の機会があったら、次回は頑張りたいと思います。

発表後の懇親会では、Androidのテストについての苦労話を、色々な方から伺うことができました。大変だという思いは皆さん一緒なのだと改めて思いました。Androidのテストについて、色々な方の考えを聴けるのは本当に参考になります!

今回の勉強会を主催してくださった@petitvioletさん、@tomoaki_imaiさん、株式会社メルカリのみなさん、どうもありがとうございました。

Appiumについての記事を@ITに寄稿しました

Android Appium

Android/iOS向けのテスト自動化ツールAppiumについての記事を、@ITさんの連載 「スマホ向け無料システムテスト自動化ツール」 に寄稿しました。

今回の記事ではAppiumのGUIフロントエンドを使ってテストを実行するところまでの手順を説明しています。 すぐに試せるように、Android向けサンプルのソースコードも一緒に公開していますので、興味の有る方はお試しください。

なお、執筆タイミングの関係で、Appiumのバージョン1.3.4を元にした記事になっています。
現在の最新版である1.3.7を動かしてみたところ、いくつかの違いがありましたので、このエントリーで紹介したいと思います。 最新版のAppiumで試すときの参考にしてください。

Windows向けのインストールパッケージについて

Windows向けのAppium 1.3.4.1は、zipファイルを展開するだけでインストール完了だったのですが、最新のAppium 1.3.7.2では、インストーラを実行してインストールするようになっています。

zipファイルの中にappium-installer.exeがありますので、それを実行するとインストールすることができます。

Mac OS X向けの外観について

Mac OS X向けのAppium Desktop Appの外観が少しだけ変わりました。バージョン1.3.4では、記事に掲載した画面スナップショットのように、設定ボタン類は左側に寄っていたのですが、1.3.7では以下のようなレイアウトになりました。

f:id:sumio_tym:20150430004916p:plain

また、悲しいことに、各種設定ダイアログの外観が見にくくなってしまいました。

f:id:sumio_tym:20150430010217p:plain

この見にくいダイアログへの変更は意図されたものではないようで、開発元のIssueとして登録されています。
いずれ改善されるとは思いますが、それまでは眼を凝らして設定項目を見るしかないですね…。

UIAutomator 2.0の日本語入力を試してみた

少し前に、UIAutomator 2.0が、Android Testing Support Libraryに入るようになりました。

https://plus.google.com/+AndroidDevelopers/posts/WCWANrPkRxg

既にセットアップ方法や、APIリファレンスも公開されています。

早速APIリファレンスを眺めてみたところ、UiObject.setText(String)の説明)に、以下のような注記があるのを見付けました。

Improvements: Post API Level 19 (KitKat release), the underlying implementation is updated to a dedicated set text accessibility action, and it also now supports Unicode.

どうも、Lollipop以降であれば、UiObject.setText(String)で日本語(Unicode)が入力できるようになっているようです。

ちょうど、Googleが公開しているサンプルが、文字を入力するものだったので、 ChangeTextBehaviorTest.javaの以下の部分を日本語に変更して動作を確認してみました。

    private static final String STRING_TO_BE_TYPED = "こんにちは";

その結果、手持ちのNexus7 (Android 5.0.2)で、普通に日本語が入力できることが確認できました。

これでUiautomator Unicode Input Helperの助けを借りずとも、日本語が入力できそうです(KitKat以前では従前通り助けが必要です)。

第9回potatotipsでRobolectricでPowerMockを使う方法を発表しました #potatotips

Android Gradle Android Studio Robolectric

2014/9/24(水)に開催された【第9回】potatotips(iOS/Android開発Tips共有会)で発表してきました。以下が発表資料です。

Android単体テストフレームワークRobolectricPowerMockを使う方法(開発環境にAndroid Studioを使う場合)を紹介する内容です。

当日の発表は、持ち時間が5分ということもあり、ほとんど結論だけの内容にしたのですが、このエントリーでは、この結論に至った経緯について少し補足したいと思います。

JDKのバージョンについて

RobolectricとPowerMockを共存させるために利用しているPowerMockAgentの問題で、JDK1.7でテストを実行しようとすると、以下のような例外が発生し、実行に失敗してしまいます。

java.lang.IllegalStateException: Unable to load Java agent; please add lib/tools.jar from your JDK to the classpath

この問題は、PowerMockのissueに登録されていて、Mavenを使う場合の回避策は書かれているのですが、Gradle/Android Studioで解決する方法がわかりませんでした。 具体的には、テスト実行時に-javaagentオプションに加えて-XX:-UseSplitVerifierを指定すればうまくいきそうなのですが、自分の環境では解決しませんでした。

この点を解決する方法が見付かれば、JDK1.7以降でも動作させることができると思います。

robolectric-gradle-pluginのバージョンについて

発表時点におけるrobolectric-gradle-pluginのリリースバージョンは0.12.0だったのですが、0.12.0ではテスト実行時のオプション引数を指定するためのjvmArgs機能が実装されていませんでした。

PowerMockAgentの方法を使ってテストを実行するときは、テスト実行時に-javaagentオプションを使って、powermock-module-javaagent-1.5.5.jarへのパスを指定する必要があります。

そのため、jvmArgs機能が実装されているmasterブランチの先端(資料作成当時のリビジョンはこちら)を自分でビルドする方法を紹介したのですが、今確認したら、発表当日に0.13.0がリリースされていたようです。

0.13.0にはjvmArgsを指定できる機能も含まれているようなので、こちらを利用すれば、わざわざ自分でビルドする必要はなさそうです。まだ0.13.0での動作確認はできていないので、近々確認してみようと思います。

RobolectricのConfigファイルの配置について

Robolectricでテストを実行するには、テスト対象アプリのAndroidManifest.xmlの場所をorg.robolectric.Config.propertiesファイルに指定する必要があります。 このファイルを置くディレクトリについて、発表ではsrc/test/resと説明しましたが、少なくともrobolectric-gradle-pluginの0.12.0ではsrc/test/resourcesが正しい置き場所でした。

その後のどこかでsrc/test/res配下を見るように仕様変更したようなのですが、意図したものなのかバグなのか分かっていません。今後またsrc/test/resから変更されるかも知れませんので、うまくテスト対象アプリが見付けられていないようなら、このファイルが正しく読み込まれているかどうか、以下の方法で確認してみると良いと思います。

  • gradle clean testDebugClassesを実行する。
  • build/test-classesディレクトリにorg.robolectric.Config.propertiesファイルが存在するかどうかを確認する。存在していれば問題なし。

Android Studioで実行できるようにするための設定について

Android StudioでRobolectricのテストを実行する方法については、id:STAR_ZERO さんによる以下の記事が非常に参考になりました。

この記事に書かれている内容をrobolectric-gradle-pluginの最新版に対応させ、PowerMock対応のための実行時オプションを追加したものが、今回の発表のベースになっています。

Javaエージェント方式 vs JUnit Rule方式

RobolectricとPowerMockの併存が難しい根本的な理由は、JUnit4の@RunWithアノテーションで指定できるテストランナーが1クラスに限定されているからです(発表スライドp.8参照)。一方、PowerMockには@RunWithを使わない方法として、以下の2通りが用意されています。

このどちらの方法を採用しても、@RunWithの問題を解決できるはずですなのですが、自分の環境では、JUnit Rule方式ではXStream周りで例外が出て起動に失敗してしまい、うまく動作しませんでした。

そのような経緯で、Javaエージェント方式を採用したのですが、Javaエージェント方式は公式ドキュメントにexperimentalと書かれていることもあり、もし例外発生を回避できる方法が見付かるなら、JUnit Rule方式がより望ましいと思います。

JUnit Rule方式を使うことができるようになれば、JDK1.6縛りの問題も解決されますし、-javaagentオプションをテスト実行時に指定する必要がなくなるため、build.gradleもかなりシンプルになるはずです。 もし解決方法をご存知の方がいらっしゃいましたら、コメントいただけると有り難いです。

さいごに

potatotipsに参加するのは今回が2回目だったのですが、前回と同様、どの発表も自分にとっては知らないことばかりで、「今度機会があったら使ってみよう」と思えるTipsが揃っていました。自分の発表もそのように感じて下さった方がいらっしゃったとしたら大変嬉しいです。

発表後の懇親会では、Androidアプリ開発にまつわる色々な視点の話を伺うことができ、とても参考になると共に、楽しい時間を過ごすことができました。自分では思い至らないような視点を持っている方が多く、自分ももっと視野を広げねば、と思った1日でした。また何かネタを見つけて発表したいと思います!

主催してくださった @ninjinkun さんを始めとするFablic,inc.の皆さん、運営サイドの皆さん、どうもありがとうございました。

android.test.casual2で発表してきました #androidcasualtest

Android uiautomator

2014/4/3(木)に開催された android.test.casual #2 でLTをしました。以下が発表資料です。

「もしもの時にも安心なuiautomatorのwatcher機能」 というタイトルで、 uiautomatorフレームワークが提供しているUiWatcher APIの振舞いを紹介しました。

今回ご紹介したUiWatcherというのは、

  • テスト対象アプリの強制終了ダイアログ表示
  • テスト対象アプリのANRダイアログ表示

のような、テストシナリオの進行とは無関係に発生する事象に対して、 どのように操作したいかを登録できる機能です。

uiautomatorが持つ、かなり特徴的な機能だと思うのですが、 公式ドキュメントにはほとんど記載がなく、 あまり知られていなさそうな雰囲気がしたので、今回発表してみました。

詳細は上記発表スライドを見ていただきたいのですが、 うまく使うと非常に便利だと思いますので、是非お試しください。

今回も、色々な立場の方の話を聴くことができて、とても励みになりました。 また次回も参加したいですね!