Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Advanced espresso #io16 extend seoul

2,095 views

Published on

에스프레소를 사용하는 방법에 대해 구글의 가이드를 설명하였습니다.

Published in: Internet
  • Be the first to comment

Advanced espresso #io16 extend seoul

  1. 1. 정승욱 Google Developer Expert 토스랩 - JANDI Android 개발자 Advanced Espresso
  2. 2. 안드로이드 테스트 안드로이드 스튜디오 안드로이드 테스트 서포트 라이브러리 Android Epsresso
  3. 3. UI 테스트 흐름
  4. 4. onView(withId(R.id.fab)).perform(click()); onView(withItemText("Jason")).perform(click()); onView(withId(R.id.et_message)) .perform(typeText("test")); onView(withId(R.id.btn_send)).perform((click()); onView(withId(android.R.id.home).perform(click()); onView(withItemText("Jason")) .check(matches(isDisplayed())); 코드로 보는 UI 테스트
  5. 5. onView(withId(R.id.fab)).perform(click()); onView(withItemText("Jason")).perform(click()); onView(withId(R.id.et_message)) .perform(typeText("test")); onView(withId(R.id.btn_send)).perform((click()); onView(withId(android.R.id.home).perform(click()); onView(withItemText("Jason")) .check(matches(isDisplayed())); 코드로 보는 UI 테스트
  6. 6. onView(withId(R.id.fab)).perform(click()); onView(withItemText("Jason")).perform(click()); onView(withId(R.id.et_message)) .perform(typeText("test")); onView(withId(R.id.btn_send)).perform((click()); onView(withId(android.R.id.home).perform(click()); onView(withItemText("Jason")) .check(matches(isDisplayed())); 코드로 보는 UI 테스트
  7. 7. onView(withId(R.id.fab)).perform(click()); onView(withItemText("Jason")).perform(click()); onView(withId(R.id.et_message)) .perform(typeText("test")); onView(withId(R.id.btn_send)).perform((click()); onView(withId(android.R.id.home).perform(click()); onView(withItemText("Jason")) .check(matches(isDisplayed())); 코드로 보는 UI 테스트
  8. 8. Espresso 의 구분 onView(Matcher<View>) // ViewMatcher -> ViewInteraction .perform(ViewAction) // ViewAction onView(Matcher<View>) .check(ViewAssertion); // ViewAssertion
  9. 9. ViewMatcher View 에 접근하기 위한 객체 Activity 나 Fragment 를 사용하면? ➡ View 가 Null 이면? ➡ Test에 NPE 처리를? “ViewMatcher 는 뷰에 접근하는 과정에서의 오동작을 에러가 아닌 테스트 실패로 간주할 수 있도록 도와준다.”
  10. 10. ViewInteraction UI 테스트의 시작점 접근한 View 정보를 담고 있음 View 의 동작을 제어 : 클릭, 텍스트 입력 등 View 의 정보를 검증 기능 제공 : 화면에 보이는지..
  11. 11. ViewAction 뷰에 클릭 또는 텍스트 입력등 다양한 동작을 제어함 동작이 완료될 때까지 대기하도록 함
  12. 12. ViewInteraction.java
  13. 13. Idle or not? handler.postDelayed(runnable, 5000); Main Looper 는 Idle 상태일까요?
  14. 14. LooperIdlingResource.java
  15. 15. QueueInterrogator.java
  16. 16. Custom IdlingResource 예시 @Override public boolean isIdleNow() { boolean idle = !isIntentServiceRunning(); if (idle && resourceCallback != null) { resourceCallback.onTransitionToIdle(); } return idle; } private boolean isIntentServiceRunning() { ActivityManager manager = (ActivityManager) context.getSystemService (Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo info : manager. getRunningServices(Integer.MAX_VALUE)) { if (RepeatService.class.getName().equals(info.service. getClassName())) { return true; } } return false; }
  17. 17. Custom IdlingResource 적용 @Before public void registerIntentServiceIdlingResource() { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); idlingResource = new IntentServiceIdlingResource( instrumentation.getTargetContext()); Espresso.registerIdlingResources(idlingResource); } @After public void unregisterIntentServiceIdlingResource() { Espresso.unregisterIdlingResources(idlingResource); }
  18. 18. 구글의 팁
  19. 19. 복사 붙여넣기 하지마라
  20. 20. 복붙 금지!!! @Test public void testXXX() { onView(withId(R.id.fab)).xxx; } @Test public void testYYY() { onView(withId(R.id.fab)).yyy; } 만약 Resource 의 ID 가 바뀐다면?
  21. 21. Robot 예제 42 입력 onView(withText("4")).perform(click()); onView(withText("2")).perform(click()); Robot.input(42); public static void input(int x) { String y = String.valueOf(x); for (int i = 0; i < y.lengn(); i++) { onView(withText(String.valueOf(y.charAt(i)))) .perform(click()); } }
  22. 22. 가능한 제공되는 Matcher 를 사용해라
  23. 23. CheatSheet
  24. 24. CountingIdlingResource 를 사용해라
  25. 25. CountingIdlingResource.java public class CountingIdlingResource { public void increment(); public void decrement(); }
  26. 26. 단 Timeout 설정을 같이 해주세요. public class IdlingPolicies { public static void setMasterPolicyTimeout(long timeout, TimeUnit unit); public static void setIdlingResourceTimeout(long timeout, TimeUnit unit); } 기본값 - IdlingResource : 5초 - MasterPolicy : 26초
  27. 27. 뷰의 정보가 아닌 동작에 집중해라.
  28. 28. 동작의 결과에 주목하자. 4가 쓰여진 뷰의 x-y 위치 같은 것은 잊어라 4가 씌여진 뷰가 있는지를 검증하라.
  29. 29. Large Test 보단 Small Test 를 많이 써라
  30. 30. LargeTest
  31. 31. Small Test 1 2 2 3 3 4
  32. 32. 원하는 화면을 바로 호출해라.
  33. 33. MyActivityTest.java @Rule new ActivityTestRule<MyActivity>(MyActivity.class) { @Override protected Intent getActivityIntent() { Intent intent = new Intent(); intent.putExtra(...); return intent; } }
  34. 34. MyActivityTest.java @Rule public ActivityTestRule<MyActivity> rule = new ActivityTestRule<MyActivity>(MyActivity.class, true, false ); @Before public void setUp() { int extra = getExtraInt(); Intent intent = new Intent(); rule.launchActivity(intent); }
  35. 35. 통제된 환경에서만 테스트 해라
  36. 36. 외부 앱 실행은 Intent 를 획득하라
  37. 37. Intent 획득 @Test public void test() { Intents.init(); ActivityResult result = createImageCaptureResult(); intending(hasAction(IMAGE_CAPTURE)).responseWith(result); // test something Intents.release(); }
  38. 38. Intent 획득 @Rule public IntentTestRule<MyAct> rule = new IntentTestRule<>(MyAct.class); @Test public void test() { ActivityResult result = createImageCaptureResult(); intending(hasAction(IMAGE_CAPTURE)).responseWith(result); // test something }
  39. 39. 애니메이션을 핸들링 하기
  40. 40. 이따금 커스텀 애니메이션은 과도하게 Handler 를 사 용하기 때문에 Idle 상태를 유지하기 어렵게 만든다.
  41. 41. UI 테스트에 실패했을 때...
  42. 42. Espresso ViewHierarchy Log Test 의 Log Console 을 읽는다. android.support.test.espresso.AmbiguousViewMatcherException: 'with id: is <2131493330>' matches multiple views in the hierarchy. Problem views are marked with '****MATCHES****' below. +------------->ImageView{id=2131493330, res-name=item_image, desc=Image, visibility=VISIBLE, width=262, height=262, has- focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is- focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0} ****MATCHES**** +------------->ImageView{id=2131493330, res-name=item_image, desc=Image, visibility=VISIBLE, width=262, height=262, has- focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is- focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0} ****MATCHES**** |
  43. 43. Custom FailureHandler public interface FailureHandler { public void handle(Throwable error, Matcher<View> viewMatcher); } Espresso.setFailureHandler(handler);
  44. 44. 느린 기기 Test 시 주의사항
  45. 45. Settings → Accessiblility → Touch and hold delay Long 으로 전환 Animation 비활성화
  46. 46. Accessibility Test 시 주의사항
  47. 47. AccessibilityValidator.enable()
  48. 48. 참고 자료 문서 - https://google.github.io/android-testing-support-library/ 영상 - https://www.youtube.com/watch?v=isihPOY2vS4 예제 코드 - https://github.com/googlesamples/android-testing - https://github.com/googlesamples/android-testing-templates - https://github.com/googlesamples/android-architecture

×