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

もしもの時にも安心なuiautomatorのwatcher機能

 もしもの時にも安心なuiautomatorのwatcher機能

android.casual.test #02 のLT資料です。
AndroidのUIテストフレームワークuiautomatorを使った試験中に、アプリ強制終了などの想定外の事象が発生したときの保険として使うことのできるUiWatcher APIについて説明しています。

TOYAMA Sumio

April 03, 2014
Tweet

More Decks by TOYAMA Sumio

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ •  ࢯ໊:  ֎ࢁ७ੜ(TOYAMA  Sumio)   @sumio_tym  (twitter),  @sumio  (github)

      http://sumio.hatenablog.com/  (blog)   •  ॴଐ:  NTTιϑτ΢ΣΞגࣜձࣾ   •  ۀ຿಺༰:   – ࣾ಺Android™ؔ࿈ϓϩδΣΫτٕज़ࢧԉ   – Androidؔ࿈ࣾ಺ݚमߨࢣ   •  ϓϥΠϕʔτ:   – Androidͷࣗಈςετ༻ͷIMEΛެ։ͯ͠·͢   https://github.com/sumio/uiautomator-­‐unicode-­‐input-­‐helper   ( )  Android  is  a  trademark  of  Google  Inc. 2  
  2. •  uiautomator:  AndroidͷUIςετπʔϧ   •  UiWatcher:    uiautomatorͷAPI   3

      ͓࿩͢͠Δ͜ͱ uiautomatorΛ࢖ͬͨࣗಈςετΛ   ΑΓrobustʹ͢ΔAPI   ʮUiWatcherʯػೳʹ͍ͭͯઆ໌͠·͢
  3. ΞδΣϯμ •  uiautomator͓͞Β͍   •  UiWatcherΛ࢖Θͳ͍ͱى͖Δ͜ͱ   •  UiWatcherͱ͸  

    – ֓ཁ   – ࢖͍ํ   – Tips  1:  UiWatcherൃಈλΠϛϯά   – Tips  2:  checkCondition()ͷ໭Γ஋   •  ·ͱΊ   4  
  4. uiautomator͓͞Β͍   ֓ཁ •  ػೳɾUIςετࣗಈԽπʔϧ(Googleۘ੡)   –  http://developer.android.com/tools/testing/ testing_ui.html  

    •  ಛ௃   –  ΞϓϦʹ·͕ͨͬͨૢ࡞γφϦΦ͕ॻ͚Δ   –  ୈࡾऀ͕࡞ͬͨΞϓϦ΋ૢ࡞Մೳ   –  ઈର࠲ඪࢦఆ͕ෆཁ   •  ཹҙ఺   –  JellyBean  (API  Level  16)Ҏ্ͷΈରԠ   –  ൺֱతγφϦΦ͕ෳࡶʹͳΓ͕ͪ   cf.  Robotium,  Espresso   6  
  5. uiautomator͓͞Β͍   ςετίʔυྫ(2/2) 8   public void test_dialogA() throws Exception

    { // ʮμΠΞϩάදࣔAʯϘλϯΛԡ͠ɺμΠΞϩά͕දࣔ͞ΕΔ·Ͱ଴ͭɻ UiObject button = new UiObject(new UiSelector().text("μΠΞϩάදࣔA")); button.clickAndWaitForNewWindow(); // ʮμΠΞϩάදࣔAʯͱදࣔ͞Ε͍ͯΔTextViewͷଘࡏΛ֬ೝ͢Δɻ UiObject dialogMessage = new UiObject(new UiSelector() .className(TextView.class).text("μΠΞϩάදࣔA")); assertTrue("Dialog not found", dialogMessage.exists()); // ʮCloseʯϘλϯΛԡͯ͠μΠΞϩά͕ফ͑Δ·Ͱ଴ͭɻ UiObject dialogOk = new UiObject(new UiSelector() .className(Button.class).text("Close")); dialogOk.click(); assertTrue("μΠΞϩά͕ফ͑·ͤΜͰͨ͠", dialogMessage.waitUntilGone(10000L));  } UI෦඼ͷݕࡧ৚݅
  6. UiWatcherͱ͸   ֓ཁ(1/2) •  ૢ࡞ର৅͕ݟ෇͔Βͳ͔ͬͨΒൃಈ͢ΔϦεφ   •  Ϧεφͷ۩ମྫ   – 

    ʮڧ੍ऴྃμΠΞϩάͷ[OK]Λԡ͢ʯ   –  ʮANRμΠΞϩάͷ[OK]Λԡ͢ʯ   –  etc.   13   ςετγφϦΦʹͱͬͯ૝ఆ֎ͷ͜ͱ͕ى͖͍ͯΔ
  7. UiWatcherͱ͸   ࢖͍ํ 1.  UiWatcherͷ࣮૷ΫϥεΛ࡞Δ   –  public  boolean  checkCondition();

      2.  ্هΛΠϯελϯεԽͯ͠ొ࿥͢Δ   –  setUp()ʹॻ͍͓ͯ͘ͷ͕Φεεϝ   3.  tearDown()࣌ʹొ࿥Λղআ͢Δ   15  
  8. •  UiWatcherͷ࣮૷Ϋϥεྫ   16   private final UiWatcher crashWatcher =

    new UiWatcher() { @Override public boolean checkForCondition() { UiObject dialogContent = new UiObject(new UiSelector() .text("໰୊͕ൃੜͨͨ͠ΊɺDialogSampleΛऴྃ͠·͢ɻ")); if (!dialogContent.exists()) { return false; } UiObject okButton = new UiObject(new UiSelector() .className(Button.class).text("OK")); try { okButton.click(); } catch (UiObjectNotFoundException e) { return false; } dialogContent.waitUntilGone(10000L); return true; } }; ڧ੍ऴྃμΠΞϩά൑ఆ [OK]ϘλϯΛԡͯ͠μΠΞϩάΛফ͢ ࣗ෼ͷग़൪͡Όͳ͔ͬͨ࣌͸falseΛฦ͢ɻ
  9. •  setUp()ͱtearDown()ͷྫ   17   private final UiWatcher crashWatcher =

    ...; // લεϥΠυࢀর private static final String CRASH_WATCHER_STRING = "Crash"; protected void setUp() throws Exception { super.setUp(); getUiDevice() .registerWatcher(CRASH_WATCHER_STRING, crashWatcher); // (ޙུ) } protected void tearDown() throws Exception { getUiDevice().resetWatcherTriggers(); getUiDevice().removeWatcher(CRASH_WATCHER_STRING); // (தུ) super.tearDown(); } UiWatcherʹϢχʔΫͳ໊લΛ෇͚ͯొ࿥ ొ࿥࣌ʹ෇໊͚ͨલΛࢦఆͯ͠ొ࿥ղআ
  10. UiWatcherͱ͸   Tips  1:  UiWatcherൃಈλΠϛϯά(1/2) •  UI෦඼ʹର͢Δૢ࡞໋ྩΛड͚ͨͱ͖ͷಈ࡞   1.  ૢ࡞ର৅෦඼Λ୳͢

      2.  ݟ෇͔ͬͨ৔߹:  ෦඼Λૢ࡞ͯ͠ൈ͚Δ   3.  ݟ෇͔Βͳ͔ͬͨ৔߹:   •  UiWatcherΛൃಈ͢Δ   •  1ඵεϦʔϓ͔ͯ͠Βretry͢Δ   •  λΠϜΞ΢τ͢ΔͱUiObjectNotFoundException   18   ૢ࡞ର৅͕ݟ෇͔Βͳ͔ͬͨͱ͖   ૢ࡞ର৅͕ݟ෇͔Βͳ͍͔΋஌Εͳ͍ͱ͖ retryͷ౓ʹൃಈ͢Δ   •  ಉҰUI෦඼ʹରͯ͠ෳ਺ճൃಈ͢Δ͜ͱ͕͋Δ   •  UI෦඼͕༗Δ(retryޙʹݟ෇͔ͬͨ)ͷʹൃಈ͢Δ͜ͱ͕͋Δ  
  11. UiWatcherͱ͸   Tips  1:  UiWatcherൃಈλΠϛϯά(2/2) •  ޡര͠ͳ͍Α͏ʹ஫ҙͯ͠checkCondition()Λ࣮ ૷͢Δ͜ͱ͕େࣄ   – 

    ࠓճͷྫͰ͸ʮڧ੍ऴྃμΠΞϩάʯ͕දࣔ͞Εͯ ͍ͳ͍ͱ͖ʹؒҧͬͯOKΛԡ͞ͳ͍Α͏ʹ͢Δ   19   @Override public boolean checkForCondition() { UiObject dialogContent = new UiObject(new UiSelector() .text("໰୊͕ൃੜͨͨ͠ΊɺDialogSampleΛऴྃ͠·͢ɻ")); if (!dialogContent.exists()) { return false; } // (ޙུ) } }; ಉҰͷςΩετ͕ɺ   ΞϓϦ಺ʹग़ݱ͢Δͱޡര͢ΔͷͰ஫ҙ  
  12. UiWatcherͱ͸   Tips  2:  checkCondition()ͷ໭Γ஋(1/2) •  UiWatcher͝ͱʹʮτϦΨʔঢ়ଶʯ͕͋Δ   •  checkCondition()͕trueΛฦ͢ͱτϦΨʔঢ়ଶ΋trueʹ

      •  Ұ౓trueʹͳͬͨτϦΨʔঢ়ଶ͸໌ࣔతʹreset͢Δ· Ͱtrueͷ··   •  ૝ఆ͞ΕΔϢʔεέʔε   –  ڧ੍ऴྃ͞Εͨճ਺Λ਺͍͑ͨ   –  ڧ੍ऴྃ͞Ε͔ͨͲ͏͔ͰγφϦΦΛ෼ذ͍ͤͨ͞   –  etc.   20   ʮτϦΨʔঢ়ଶΛtrueʹ͢Δ͔Ͳ͏͔ʯΛද͢
  13. UiWatcherͱ͸   Tips  2:  checkCondition()ͷ໭Γ஋(2/2) •  τϦΨʔঢ়ଶؔ࿈ͷAPI  (UiDeviceΫϥε)   – 

    setWatcherTriggered(String  watcherName)   –  hasWatcherTriggered(String  watcherName)   –  resetWatcherTriggers()   –  hasAnyWatcherTriggered()   •  UiWatcherొ࿥ղআͱͷؔ܎   –  ొ࿥ղআͯ͠΋τϦΨʔঢ়ଶ͸ΫϦΞ͞Εͳ͍   –  ొ࿥ղআ࣌͸resetWatcherTriggers()΋ݺΜͰ͓͘ͱ٢   21  
  14. ·ͱΊ •  uiautomatorͷUiWatcherʹ͍ͭͯઆ໌͠·ͨ͠   –  UI෦඼͕ݟ෇͔Βͳ͔ͬͨ࣌ʹݺͼग़͞ΕΔϦεφ   –  ςετର৅ΞϓϦʹࢥΘ͵ࣄଶ͕ൃੜͯ͠΋ςετ Λଓ͚ΒΕΔΑ͏ʹͳΓ·͢

      •  UiWatcherͷࡉ͔͍ৼΔ෣͍Λઆ໌͠·ͨ͠   –  ൃಈλΠϛϯά   –  τϦΨʔঢ়ଶ   22   ׆༻ͯ͠ɺΑΓrobustͳςετΛ໨ࢦ͠·͠ΐ͏!