Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Androidテスティング実践2 システムテスト編

Androidテスティング実践2 システムテスト編

NTTソフトウェア社内のソフト道場研修で実施した、Androidテスティング実践研修テキストの2. システムテスト編です。

More Decks by NTTテクノクロス株式会社

Other Decks in Technology

Transcript

  1. 2. システムテストの⾃動化 !  この研修で紹介するツールの使い分け !  Robotium (座学+演習) !  Espresso (座学+演習)

    !  UI Automator (座学+演習) !  Appium (座学) 57 Copyright © 2016, NTT Software Corporation.
  2. 【Robotium】テストコードの書き⽅: setup 64 @RunWith(AndroidJUnit4.class) public class MyRobotiumTest { // ActivityTestRuleの宣⾔は省略

    @Rule public ActivityTestRule<...> activityTestRule = ...; private Solo solo; @Before public void setUp() throws Exception { solo = new Solo(InstrumentationRegistry. getInstrumentation(), activityTestRule.getActivity()); } ! Robotiumの主要クラスSoloをインスタンス化する Copyright © 2016, NTT Software Corporation.
  3. 【Robotium】テストコードの書き⽅: tear down 65 ... @After public void tearDown() throws

    Exception { solo.finishOpenedActivities(); } } ! Solo#finishOpenedActivities()を呼び出す Copyright © 2016, NTT Software Corporation.
  4. 【Robotium】テスト⽤APIの紹介: 位置指定操作 ! UI部品の番号を指定してクリック 68 ⑦ ② ③ ④ ⑤ ⑥

    ① solo.clickInList(4); リストの4⾏⽬(1始まり)をクリック ⑦ ② ③ ④ ⑤ ⑥ ① ⓪ index 7(0始まり)のボタンをクリック solo.clickOnButton(7); Copyright © 2016, NTT Software Corporation.
  5. 【Robotium】テスト⽤APIの紹介: ⽂字列取得・⼊⼒ ! 表⽰⽂字列の取得・テキスト⼊⼒ 69 メソッド(Soloクラス) 概要 searchText(String) 指定された正規表現にマッチする⽂字列を表⽰し ているUI部品を探す。⾒付かればtrueを返す。 enterText(int,

    String) 指定されたindex(0始まり)に存在するEditText に対して、指定された⽂字列を⼊⼒する。 getText(String) 指定された正規表現にマッチする⽂字列を表⽰し ているTextViewを返す。 getEditText(int) 指定されたindex(0始まり)に存在するEditText を返す。 ! 画⾯のどこにでも良いから⽂字列が表⽰されているか確認する場合は searchText()が便利 ! 特定のViewに表⽰されている⽂字列を確認する場合は、 getText()・getEditText()でTextView・EditTextを取得してから TextView#getText()・EditText#getText()を使う Copyright © 2016, NTT Software Corporation.
  6. 【Robotium】テスト⽤APIの紹介: そのほか ! そのほか 70 メソッド(Soloクラス) 概要 assertCurrentActivity(St ring, Class) 現在の画⾯が指定されたActivity(クラス)

    であることをassertする。 takeScreenshot() 画⾯のスクリーンショットを撮る。 /sdcard/Robotium-Screenshots/に保存。 clickOnWebElement(By) 指定された検索条件(Byオブジェクト)に合致した WebView内HTML部品をクリックする。 typeTextInWebElement(By, String) 指定された検索条件(Byオブジェクト)に合致した WebView内HTML部品(フォーム)に対して、 指定された⽂字列を⼊⼒する。 ˞ スクリーンショットを撮る場合は、テスト対象アプリ側に、以下のパー ミッション宣⾔が必要 <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" /> Copyright © 2016, NTT Software Corporation.
  7. 【Robotium】演習2-2 ! Robotiumを使って、以下のテストシナリオを実現してくだ さい。 " 1つめのEditTextに「5」を⼊⼒する " 2つめのEditTextに「8」に⼊⼒する " 「この画⾯に表⽰」ボタンをクリックする " 画⾯のどこかに「13」と表⽰されることを確認する ! テストクラス名: RobotiumTest ! 参考スライド

    " ①基礎編【演習1-1】ATSLのための設定 " 【Robotium】環境設定 " 【Robotium】テストコードの書き⽅ " 【Robotium】テスト⽤APIの紹介: 表⽰⽂字列の取得・テキスト⼊⼒ 71 Copyright © 2016, NTT Software Corporation.
  8. 【Espresso】概要 ! Google謹製の、ホワイトボックステスト向けUI テストフレームワーク ! コードの簡潔さ、信頼性の⾼さに定評有り ! APIレベル8, 10, 15-19, 21に対応 " 概ねAndroid 2.2以上(3.x除く)

    ! Instrumented Testとして実装 ! URL: https://goo.gl/x8eP5C https://goo.gl/lmrlJI ! Apache License 2.0 Copyright © 2016, NTT Software Corporation. 73 https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html よりロゴを引⽤
  9. 【Espresso】環境設定 ! ATSLの設定に加えて、app/build.gradleに以下を追加 76 dependencies { // ATSLの設定は省略 androidTestCompile \ 'com.android.support.test.espresso:espresso-core:2.2.2'

    } モジュール名:バージョン 概要 espresso-intents:2.2.2 別Activity起動時に発⾏するIntentを確認できる 起動元Intentのモックを作成できる espresso-web:2.2.2 WebView内部をテストできる ! 以下の追加モジュールもあり(詳細は省略) Copyright © 2016, NTT Software Corporation.
  10. 【Espresso】テストコードの書き⽅: setup/tear down 77 @RunWith(AndroidJUnit4.class) public class MyEspressoTest { @Rule

    public ActivityTestRule<...> activityTestRule = ...; ... } ! ATSLのための準備だけでOK Copyright © 2016, NTT Software Corporation.
  11. 【Espresso】テスト⽤APIの紹介: 概要 78 概要 ViewMatcher Viewの検索条件を指定する。ViewMatchersクラス参照。 withId(), withClassName(), withText(), ...

    ※hamcrestのallOf(), not(), is(),なども使える ViewAction Viewに対する操作を指定する。ViewActionsクラス参照。 clearText(), typeText(), click(), ... ViewAssertion 確認条件を指定する。ViewAssertionsクラス参照。 doesNotExist(), matches(ViewMatcher), ... onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion); ! 以下の基本形を理解する ˞ perform(), check()は省略可 !  「ViewMatcher」にあてはまる Viewに対して !  「ViewAction」を実⾏した結果 !  そのViewが「ViewAssertion」 を満たすことを確認する Copyright © 2016, NTT Software Corporation.
  12. 【Espresso】テスト⽤APIの紹介: 概要 Javadoc http://goo.gl/UwGTdf (android.support.test.espresso.*パッケージ) Espresso Cheat Sheet https://goo.gl/6xcuqd 以下の3クラスが重要

    " android.support.test.espresso.matcher.ViewMatchers " android.support.test.espresso.action.ViewActions " android.support.test.espresso.assertion.ViewAssertions Copyright © 2016, NTT Software Corporation. 79
  13. 【Espresso】テスト⽤APIの紹介: ViewMatchers ! 検索条件を表すメソッドが定義されている 80 メソッド 概要 withId(int) 指定されたIDを持つView withText(String) 指定されたテキストが表⽰されている

    View withContentDescription(String) 指定されたcontentDescription属性を 持ったView withClassName(Matcher<String>) 指定されたクラス名のView ※引数には「is(クラス名)」を指定する ! hamcrestのmatcherを使うこともある(CoreMatchers) " allOf(条件1, 条件2, ...) " anyOf(条件1, 条件2, ...) " is() " not() Copyright © 2016, NTT Software Corporation.
  14. 【Espresso】テスト⽤APIの紹介: ViewActions ! onView()で特定したViewに対する操作を表すメソッド が定義されている 81 メソッド 概要 click() クリックする pressBack()

    戻るキーを押す(どのViewに対して実⾏しても同じ) typeText(String) 指定された⽂字列を⼊⼒する scrollTo() onView()で指定されたViewまでスクロールする Copyright © 2016, NTT Software Corporation.
  15. 【Espresso】テスト⽤APIの紹介: ViewAssertions ! onView()で特定したViewに対してチェックするメソッ ドが定義されている 82 メソッド 概要 doesNotExist() そのViewが存在しないことを確認する matches(Matcher)

    そのViewが、引数で指定した条件を満たしていることを確 認する ! maches()の引数には、任意のViewMatchersが指定できる " テキスト"text"が表⽰されているか確認する matches(withText("text")) " Viewが画⾯に表⽰されていることを確認する matches(isDisplayed()) Copyright © 2016, NTT Software Corporation.
  16. 【Espresso】実例紹介(1/2) ! TextView (IDはR.id.textview)に"Hello"と表⽰されてい ることを確認する。 83 onView(withId(R.id.textview)) .check(matches(withText("Hello"))); ! "Press Me"と書かれているボタンを押す。 onView(withText("Press

    Me")).perform(click()); ! "Hello"と書かれているボタンを押す。 ただし、"Hello"と書かれているTextViewも存在。 onView(allOf(withClassName(is(Button.class.getName())), withText("Hello"))) .perform(click()); Copyright © 2016, NTT Software Corporation.
  17. 【Espresso】実例紹介(2/2) ! EditText (IDはR.id.input)に"Hello"と⼊⼒してからソフ トウェアキーボードを閉じる。 84 onView(withId(R.id.input)) .perform(typeText("Hello"), closeSoftKeyboard()); ! 画⾯外にあるかも知れない"Press Me"と書かれているボ

    タンを押す。 onView(withText("Press Me")) .perform(scrollTo(), click()); ※perform()の引数に複数ViewActionを並べると、左から順番に実⾏する。 Copyright © 2016, NTT Software Corporation.
  18. 【UI Automator】環境設定 ! ATSLの設定に加えて、app/build.gradleに以下を追加 91 dependencies { // ATSLの設定は省略 androidTestCompile \

    'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' } Copyright © 2016, NTT Software Corporation.
  19. 【UI Automator】テストコードの書き⽅ 92 @RunWith(AndroidJUnit4.class) public class MyUiautomatorTest { @Rule public

    ActivityTestRule<...> activityTestRule = ...; private UiDevice uiDevice; @Before public void setUp() throws Exception { uiDevice = UiDevice.getInstance(InstrumentationRegistry .getInstrumentation()); } ... } ! ATSLの設定に加えて UiDeviceオブジェクトの初期化が必要 Copyright © 2016, NTT Software Corporation.
  20. 【UI Automator】テスト⽤APIの紹介: 検索(1/2) ! 条件にあったUI部品を検索する 93 UiObject uiObject = uiDevice.findObject(<検索条件1>) //

    または UiObject2 uiObject = uiDevice.findObject(<検索条件2>) ! 検索条件1はUiSelectorオブジェクトで表現 //検索条件1 new UiSelector().text("OK").className(Button.class) ! 検索条件2はBySelectorオブジェクトで表現 //検索条件2 By.text("OK").clazz(Button.class) Copyright © 2016, NTT Software Corporation.
  21. 【UI Automator】テスト⽤APIの紹介: 検索(2/2) 94 ! UiSelector検索条件 (UiObject向け) メソッド 概要 className(Class) Viewのクラス(EditTextやButtonなど)を条件に指定する

    text(String) Viewの表⽰⽂字列を条件に指定する description(String) ViewのcontentDescription属性値を条件に指定する resourceId(String) ViewのリソースID(⽂字列表現)を条件に指定する ! BySelector検索条件 (UiObject2向け) メソッド 概要 clazz(Class) Viewのクラス(EditTextやButtonなど)を条件に指定する text(String) Viewの表⽰⽂字列を条件に指定する desc(String) ViewのcontentDescription属性値を条件に指定する res(String) ViewのリソースID(⽂字列表現)を条件に指定する Copyright © 2016, NTT Software Corporation.
  22. 【UI Automator】テスト⽤APIの紹介: UiObject系 ! UiObject/UiObject2で同名のメソッド 95 メソッド 概要 click() クリックする setText(String)

    指定された⽂字列を⼊⼒する getText() 設定されている⽂字列を取得する isFocused() フォーカスが当たっているかどうかを取得する Copyright © 2016, NTT Software Corporation.
  23. 【UI Automator】テスト⽤APIの紹介: UiObject系 96 ! 「OK」ボタンをクリックする例 // UiObjectを使う場合 UiObject okButton =

    uiDevice.findObject(new UiSelector().text("OK"). className(Button.class)); okButton .click(); // UiObject2を使う場合 UiObject2 okButton2 = uiDevice.findObject(By.text("OK").clazz(Button.class)); okButton2.click(); Copyright © 2016, NTT Software Corporation.
  24. 【UI Automator】テスト⽤APIの紹介: 同期系(1/4) ! UiObjectを使うときはUiObjectのメソッドを呼ぶ 97 メソッド(引数はタイムアウト値) 概要 clickAndWaitForNewWindow(long) クリックしてから、新しい窓(ダイアログ など)が表⽰されるまで待つ

    waitForExists(long) このViewが表⽰されるまで待つ // 「OK」ボタンを押して、ダイアログが表⽰されるまで待つ UiObject okButton = uiDevice.findObject(new UiSelector().text("OK"). className(Button.class)); // ダイアログが表⽰されるまで2000msec待つ。タイムアウト時はテスト失敗。 assertThat(okButton.clickAndWaitForNewWindow(2000L), is(true)); // ここから表⽰されたダイアログに対する操作を⾏う ! サンプルコード ※タイムアウトした場合は、falseが返される Copyright © 2016, NTT Software Corporation.
  25. 【UI Automator】テスト⽤APIの紹介: 同期系(2/4) ! UiObject2は以下の汎⽤的なメソッドを使う 98 メソッド(引数は条件とタイムアウト値) 概要 clickAndWait(EventCondition, long) クリックしてから、指定された条件が満

    たされるまで待つ wait(SearchCondition, long) ※UiObject2とUiDeviceの両⽅に存在 指定された条件が満たされるまで待つ wait(UiObject2Condition, long) 指定された条件が満たされるまで待つ ! 良く使う「条件」はUntilクラスに⽤意されている Untilクラスのstaticメソッド 概要 newWindow() 新しい窓(ダイアログ)が表⽰されるまで textEquals(String) 表⽰⽂字列が引数で指定された通りになるまで gone(BySelector) 条件に合致するViewが⾒付からなくなるまで ※タイムアウトした場合は、null/0/falseが返される Copyright © 2016, NTT Software Corporation.
  26. 【UI Automator】テスト⽤APIの紹介: 同期系(3/4) 99 ! サンプルコード // 「OK」ボタンを押して、ダイアログが表⽰されるまで待つ UiObject2 okButton2 =

    uiDevice.findObject(By.text("OK").clazz(Button.class)); // ダイアログが表⽰されるまで2000msec待つ boolean result = okButton2.clickAndWait(Until.newWindow(), 2000L); // タイムアウトしたときはテストを失敗させる assertThat(result, is(true)); // ここからダイアログの操作などを⾏う Copyright © 2016, NTT Software Corporation.
  27. 【UI Automator】インスペクタの利⽤ ! Viewの検索条件は、画⾯の⾒た⽬だけでは分からない ! 調査ツール uiautomatorviewer を使う 1.  Android Device Monitor起動

    2.  [Devices]タブで調査したい デバイスを選ぶ 3.  uiautomatorボタンを押す 102 Copyright © 2016, NTT Software Corporation.
  28. 【UI Automator】Tips: UiScrollable ! スクロールすれば現れる画⾯外の要素を操作できる 103 // 標準ホームアプリのアプリ⼀覧から、画⾯外にある //「⾜し算アプリ」アイコンをタップして起動する。 UiScrollable appViews

    = new UiScrollable(new UiSelector(). scrollable(true)); // スクロール⽅向を⽔平⽅向に設定 appViews.setAsHorizontalList(); // "⾜し算アプリ"アプリを起動する UiObject myApp = appViews.getChildByText(new UiSelector(). className(TextView.class), "⾜し算アプリ"); myApp.clickAndWaitForNewWindow(); Copyright © 2016, NTT Software Corporation.
  29. 【UI Automator】Tips: ⽇本語⼊⼒ ! UiObject/UiObject2クラスの setText(String)メソッド " Android 5.0以上: ⽇本語⼊⼒OK " Android 4.4以下:

    指定できるのはASCII⽂字のみ ! Android 4.4以下で⽇本語を使う場合は専⽤のIMEを使う " UIAutomator Unicode Input Helper https://github.com/sumio/uiautomator-unicode-input-helper Copyright © 2016, NTT Software Corporation. 104 // 上記IMEをインストールした状態で実⾏する。 // 「&」が含まれていないASCII⽂字の⼊⼒は今まで通り UiObject editText = uiDevice.findObject(...); editText.setText("Thank you"); // それ以外の⽂字を⼊⼒する時はUtf7ImeHelper.e()で⽂字列をラップする editText.setText(Utf7ImeHelper.e("ありがとう"));
  30. 【Appium】概要 Copyright © 2016, NTT Software Corporation. 107 ! End2End UIテストフレームワーク

    ! Android 2.3.3以上/iOS 6.0以上両対応 ! 別アプリにまたがったテストができる ! Selenium WebDriverと同様にテストが書ける ! URL: http://appium.io/ ! Apache License 2.0 https://github.com/appium よりロゴを引⽤
  31. 【Appium】アーキテクチャ Copyright © 2016, NTT Software Corporation. 108 http://www.atmarkit.co.jp/ait/articles/1504/27/news025.html より引⽤

    ! Appiumサーバ: クライアント-テスト対象端末間のプロ キシとして動作 ! テストスクリプトのプログラム⾔語は⾊々選べる
  32. 【Appium】テストプロジェクトのセットアップ ! (Androidではない)通常のJavaプロジェクト " EclipseやIntelliJ IDEAなどで。 ! build.gradle 112 apply plugin: 'java' //

    JavaソースコードのエンコーディングをUTF-8とする。 def defaultEncoding = 'UTF-8' tasks.withType(AbstractCompile).each { it.options.encoding = defaultEncoding } repositories { mavenCentral() } dependencies { // Appiumクライアントライブラリを利⽤するための宣⾔ testCompile 'io.appium:java-client:3.4.0' testCompile 'junit:junit:4.12' } Copyright © 2016, NTT Software Corporation.
  33. 【Appium】テストコードの書き⽅: setup ! AndroidDriverを初期化する ! そのためにDesired Capabilityの指定が必要 113 public class AppiumTest {

    private AndroidDriver<MobileElement> mDriver; @Before public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(CapabilityType.BROWSER_NAME, ""); ... mDriver = new AndroidDriver<>( new URL("http://localhost:4723/wd/hub"), capabilities); } Copyright © 2016, NTT Software Corporation.
  34. 【Appium】テストコードの書き⽅: tear down ! AndroidDriverを終了する 114 ... @After public void tearDown()

    throws Exception { mDriver.quit(); } } Copyright © 2016, NTT Software Corporation.
  35. 【Appium】テスト⽤APIの紹介: 概要 ! 基本形 Copyright © 2016, NTT Software Corporation. 116

    WebElement elem = mDriver.findElement(<検索条件>); elem.<操作> ! 検索条件(Byクラス・MobileByクラス) http://www.atmarkit.co.jp/ait/articles/1506/02/news017_2.html#031 ! 操作(WebElementクラスのメソッド) http://www.atmarkit.co.jp/ait/articles/1506/02/news017_2.html#034 ! 状態取得(WebElementクラスのメソッド) http://www.atmarkit.co.jp/ait/articles/1506/02/news017_2.html#035