수색…


비고

에스프레소

에스프레소 치트 시트는 당신이 당신의 시험을 쓰고 당신이 시험하고 싶은 것을 도울 것입니다 :

https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/

또한 참조 할 수있는 좋은 곳은 공식 문서입니다.

https://google.github.io/android-testing-support-library/docs/espresso/index.html

Google 고급 에스프레소 비디오 추천 : https://www.youtube.com/watch?v=isihPOY2vS4

문제 해결

  • 스크롤 할 때 먼저 키보드를 닫아야합니다.

Watchout : "Espresso"버전을 사용하지 않으면 ViewAction 외부에서 사용할 때 아무 것도하지 않습니다. ViewAction 버전에 정확히 동일한 메소드 이름이 있으므로 가져 오기가있는 경우에는 분명하지 않을 수 있습니다.

ViewActions.closeSoftKeyboard;
Espresso.closeSoftKeyboard();
  • 개별적으로 테스트하지 않고 스위트에서 테스트를 실행하는 경우 이전 테스트의 작업이 계속 실행 중일 수 있습니다. 이전 테스트의 onDestroy ()가 onResume () 테스트 이전에 호출되는 것에 의존하지 마십시오. 실제로 버그입니다 . http://b.android.com/201513

에스프레소 설정

Android 앱 모듈의 build.gradle 파일에서 다음 종속성을 추가하십시오.

dependencies {   
    // Android JUnit Runner     
    androidTestCompile 'com.android.support.test:runner:0.5'
    // JUnit4 Rules
    androidTestCompile 'com.android.support.test:rules:0.5'
    // Espresso core
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
    // Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
    androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
    //UI Automator tests
    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.2.2'
}

build.gradle 파일의 testInstrumentationRunner 매개 변수에 AndroidJUnitRunner 를 지정하십시오.

android {

  defaultConfig {
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  }

}

또한 의도적 조롱 지원을 제공하기 위해이 종속성을 추가하십시오.

androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'

그리고 이것을 웹뷰 테스트 지원에 추가하십시오.

// Espresso-web for WebView support
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2'

에스프레소 테스트 클래스 만들기

다음 Java 클래스를 src / androidTest / java에 놓고 실행하십시오.

public class UITest {

  @Test public void Simple_Test() {
    onView(withId(R.id.my_view))         // withId(R.id.my_view) is a ViewMatcher
        .perform(click())                // click() is a ViewAction
        .check(matches(isDisplayed()));  // matches(isDisplayed()) is a ViewAssertion
  }

}

목록 열기 DrawerLayout

public final class DrawerLayoutTest  {

  @Test public void Open_Close_Drawer_Layout() {
    onView(withId(R.id.drawer_layout)).perform(actionOpenDrawer());
    onView(withId(R.id.drawer_layout)).perform(actionCloseDrawer());
  }

  public static ViewAction actionOpenDrawer() {
    return new ViewAction() {
      @Override public Matcher<View> getConstraints() {
        return isAssignableFrom(DrawerLayout.class);
      }

      @Override public String getDescription() {
        return "open drawer";
      }

      @Override public void perform(UiController uiController, View view) {
        ((DrawerLayout) view).openDrawer(GravityCompat.START);
      }
    };
  }

  public static ViewAction actionCloseDrawer() {
    return new ViewAction() {
      @Override public Matcher<View> getConstraints() {
        return isAssignableFrom(DrawerLayout.class);
      }

      @Override public String getDescription() {
        return "close drawer";
      }

      @Override public void perform(UiController uiController, View view) {
        ((DrawerLayout) view).closeDrawer(GravityCompat.START);
      }
    };
  }
  
}

에스프레소 간단한 UI 테스트

UI 테스트 도구

요즘 주로 UI 테스트에 사용되는 두 가지 주요 도구는 Appium과 Espresso입니다.

Appium 에스프레소
블랙 박스 테스트 흰색 / 회색 상자 테스트
당신이 보는 것은 당신이 테스트 할 수있는 것이다. 응용 프로그램의 내부 동작을 변경하고 테스트를 위해 준비 할 수 있습니다 (예 : 테스트를 실행하기 전에 데이터베이스 또는 공유 미리 참조에 일부 데이터 저장).
통합 엔드 투 엔드 테스트 및 전체 사용자 플로우에 주로 사용됩니다. 화면 및 / 또는 흐름의 기능 테스트
iOS 및 Android에서 작성된 테스트를 추상화 할 수 있습니다. 안드로이드 전용
잘 지원되는 잘 지원되는
셀레늄 그리드로 여러 장치에서 병렬 테스트 지원 상자 평행 테스트가 아니라 진정한 Google 지원이 나올 때까지 Spoon 같은 플러그인이 존재합니다.

에스 프레소를 프로젝트에 추가하는 방법

dependencies {
  // Set this dependency so you can use Android JUnit Runner
  androidTestCompile 'com.android.support.test:runner:0.5'
  // Set this dependency to use JUnit 4 rules
  androidTestCompile 'com.android.support.test:rules:0.5'
  // Set this dependency to build and run Espresso tests
  androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
  // Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.2.2'
}

참고 최신 지원 라이브러리, 주석 등을 사용하는 경우 충돌을 피하기 위해 이전 버전을 에스프레소에서 제외해야합니다.

    // there is a conflict with the test support library (see http://stackoverflow.com/questions/29857695)
    // so for now re exclude the support-annotations dependency from here to avoid clashes
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }
    // exclude a couple of more modules here because of <http://stackoverflow.com/questions/29216327> and
    // more specifically of <https://code.google.com/p/android-test-kit/issues/detail?id=139>
    // otherwise you'll receive weird crashes on devices and dex exceptions on emulators
    // Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
    androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.android.support', module: 'design'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }
    //excluded specific packages due to https://code.google.com/p/android/issues/detail?id=183454
    androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }

    androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }

    androidTestCompile('com.android.support.test:runner:0.5') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }
    androidTestCompile('com.android.support.test:rules:0.5') {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude module: 'support-annotations'
        exclude module: 'recyclerview-v7'
        exclude module: 'support-v4'
        exclude module: 'support-v7'
    }

이러한 수입 외에도 android.instanceConfig에 build.gradle에 Android 계측 테스트 러너를 추가해야합니다.

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

기기 설정

비정상적 테스트의 경우 장치에서 다음 설정을 지정하는 것이 좋습니다.

  • 개발자 옵션 / 애니메이션 비활성화 - 테스트의 불편 함을 줄입니다.
  • 개발자 옵션 / 깨어있는 상태 유지 - 테스트 전용 장치가있는 경우 유용합니다.
  • 개발자 옵션 / 로거 버퍼 크기 - 휴대 전화에서 매우 큰 테스트 제품군을 실행하는 경우 높은 숫자로 설정
  • 접근성 / 터치 앤 홀드 지연 - 에스프레소의 도청에 대한 문제를 피하기위한 길다.

현실 세계에서 하차 한거야? 그럼 이제 그걸로 작은 테스트를 설정하는 방법을 살펴 보겠습니다.

테스트 작성

다음과 같은 화면이 있다고 가정 해 보겠습니다. 에스 프레소 테스트를위한 복잡한 스크린 화면에는 다음이 포함됩니다.

  • 텍스트 입력 필드 - R.id.textEntry
  • 클릭하면 입력 한 텍스트가있는 스낵바 를 보여주는 버튼 - R.id.shownSnackbarBtn
  • 사용자 입력 텍스트가 포함되어야하는 snackbar - android.support.design.R.id.snackbar_text

이제 우리의 흐름을 테스트 할 클래스를 만들 수 있습니다.

/**
* Testing of the snackbar activity.
**/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SnackbarActivityTest{
    //espresso rule which tells which activity to start
    @Rule
    public final ActivityTestRule<SnackbarActivity> mActivityRule = 
        new ActivityTestRule<>(SnackbarActivity.class, true, false);


    @Override
    public void tearDown() throws Exception {
        super.tearDown();
        //just an example how tear down should cleanup after itself
        mDatabase.clear();
        mSharedPrefs.clear();
    }
    
    @Override
    public void setUp() throws Exception {
        super.setUp();
        //setting up your application, for example if you need to have a user in shared
        //preferences to stay logged in you can do that for all tests in your setup
        User mUser = new User();
        mUser.setToken("randomToken");
    }
    
    /**
    *Test methods should always start with "testXYZ" and it is a good idea to 
    *name them after the intent what you want to test
    **/
    @Test
    public void testSnackbarIsShown() {
        //start our activity
        mActivityRule.launchActivity(null);
        //check is our text entry displayed and enter some text to it
        String textToType="new snackbar text";
        onView(withId(R.id.textEntry)).check(matches(isDisplayed()));
        onView(withId(R.id.textEntry)).perform(typeText(textToType));
        //click the button to show the snackbar
        onView(withId(R.id.shownSnackbarBtn)).perform(click());
        //assert that a view with snackbar_id with text which we typed and is displayed
        onView(allOf(withId(android.support.design.R.id.snackbar_text), 
        withText(textToType))) .check(matches(isDisplayed()));
    }
}

당신이 알아 차렸 듯이 자주 올 수있는 3-4 가지가 있습니다 :

onView (withXYZ) <- viewMatchers를 사용하면 화면에서 요소를 찾을 수 있습니다

<- viewActions를 수행 (click ()) 하면 이전에 찾은 요소에 대한 작업을 실행할 수 있습니다

check (matches (isDisplayed ())) <- viewAssertions, 이전에 찾은 화면에서 수행 할 검사

이 외에도 다음의 사이트도 있습니다. https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html

이제는 클래스 이름 / 테스트를 마우스 오른쪽 단추로 클릭하고 테스트 실행 또는 명령을 선택하여 테스트를 실행할 수 있습니다.

./gradlew connectedFLAVORNAMEAndroidTest

내비게이션

@Test
public void testUpNavigation() {
    intending(hasComponent(ParentActivity.class.getName())).respondWith(new Instrumentation.ActivityResult(0, null));

    onView(withContentDescription("Navigate up")).perform(click());

    intended(hasComponent(ParentActivity.class.getName()));
}

이는 일시적인 해결책이며 동일한 내용 설명이있는 다른보기와 충돌합니다.

보기에서 작업 수행

perform 메소드를 사용하여 뷰에서 ViewActions 을 수행 할 수 있습니다.
ViewActions 클래스는 다음과 같이 가장 일반적인 액션에 대한 헬퍼 메소드를 제공합니다.

ViewActions.click()
ViewActions.typeText()
ViewActions.clearText()

예를 들어,보기를 클릭하려면 :

onView(...).perform(click());
onView(withId(R.id.button_simple)).perform(click());

하나의 작업 수행으로 둘 이상의 작업을 실행할 수 있습니다.

onView(...).perform(typeText("Hello"), click());

작업중인 뷰가 ScrollView (세로 또는 가로) 내에있는 경우 scrollTo() 와 함께 typeText() 예 : click()typeText() )를 표시해야하는 이전 작업을 고려 click() . 이렇게하면 다른 작업으로 넘어 가기 전에보기가 표시됩니다.

onView(...).perform(scrollTo(), click());

onView로보기 찾기

ViewMatchers 를 사용하면 현재 뷰 계층 구조에서 뷰를 찾을 수 있습니다.

보기를 찾으려면 올바른보기를 선택하는보기 일치 프로그램과 함께 onView() 메소드를 사용하십시오. onView() 메소드는 ViewInteraction 유형의 객체를 반환합니다.

예를 들어 R.id 찾는 것은 다음과 같이 간단합니다.

onView(withId(R.id.my_view))

텍스트가있는보기 찾기 :

onView(withText("Hello World"))

에스프레소 주문 습작가

기본적으로 에스프레소에는 수표 또는 상호 작용을 수행하는 데 필요한보기를 찾는 데 도움이되는 많은 매처가 있습니다.

가장 중요한 것들은 다음 속임수 시트에서 찾을 수 있습니다 :

https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/

matchers의 몇 가지 예는 다음과 같습니다.

  • withId (R.id.of_object_you_are_looking_for);
  • withText ( "당신이 가지고 있다고 기대하는 어떤 텍스트");
  • isDisplayed () <- check는 가시의 뷰입니다.
  • doesNotExist () <- 뷰가 존재하지 않는지 확인

이 모든 것은 일상적으로 사용하는 데 매우 유용하지만 사용자 정의 matcher를 작성하는 것이 복잡한보기를 가지고 있다면 테스트를보다 읽기 쉽게 만들어 다른 곳에서 재사용 할 수 있습니다.

확장 할 수있는 가장 일반적인 matcher 유형은 2 가지입니다. TypeSafeMatcher BoundedMatcher

TypeSafeMatcher를 구현하면 일치하는 뷰와 일치하는 일부 유형의 속성과 일치하는 뷰어의 인스턴스를 확인할 필요가 있습니다.

예를 들어, 이미지보기의 유효성을 검사하는 안전 일치 자 (valid matcher)에는 올바른 drawable이 있습니다.

public class DrawableMatcher extends TypeSafeMatcher<View> {

    private @DrawableRes final int expectedId;
    String resourceName;
    
    public DrawableMatcher(@DrawableRes int expectedId) {
        super(View.class);
        this.expectedId = expectedId;
    }

    @Override
    protected boolean matchesSafely(View target) {
        //Type check we need to do in TypeSafeMatcher
        if (!(target instanceof ImageView)) {
            return false;
        }
        //We fetch the image view from the focused view
        ImageView imageView = (ImageView) target;
        if (expectedId < 0) {
            return imageView.getDrawable() == null;
        }
        //We get the drawable from the resources that we are going to compare with image view source
        Resources resources = target.getContext().getResources();
        Drawable expectedDrawable = resources.getDrawable(expectedId);
        resourceName = resources.getResourceEntryName(expectedId);

        if (expectedDrawable == null) {
            return false;
        }
        //comparing the bitmaps should give results of the matcher if they are equal
        Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
        Bitmap otherBitmap = ((BitmapDrawable) expectedDrawable).getBitmap();
        return bitmap.sameAs(otherBitmap);
    }


    @Override
    public void describeTo(Description description) {
        description.appendText("with drawable from resource id: ");
        description.appendValue(expectedId);
        if (resourceName != null) {
            description.appendText("[");
            description.appendText(resourceName);
            description.appendText("]");
        }
    }
}

matcher의 사용법은 다음과 같이 감쌀 수 있습니다 :

  public static Matcher<View> withDrawable(final int resourceId) {
    return new DrawableMatcher(resourceId);
}

 onView(withDrawable(R.drawable.someDrawable)).check(matches(isDisplayed()));

바운딩 된 matchers는 유형 검사를 수행하지 않아도 비슷하지만 자동으로 수행됩니다.

 /**
 * Matches a {@link TextInputFormView}'s input hint with the given resource ID
 *
 * @param stringId
 * @return
 */
public static Matcher<View> withTextInputHint(@StringRes final int stringId) {
    return new BoundedMatcher<View, TextInputFormView>(TextInputFormView.class) {
        private String mResourceName = null;

        @Override
        public void describeTo(final Description description) {
            //fill these out properly so your logging and error reporting is more clear
            description.appendText("with TextInputFormView that has hint ");
            description.appendValue(stringId);
            if (null != mResourceName) {
                description.appendText("[");
                description.appendText(mResourceName);
                description.appendText("]");
            }
        }

        @Override
        public boolean matchesSafely(final TextInputFormView view) {
            if (null == mResourceName) {
                try {
                    mResourceName = view.getResources().getResourceEntryName(stringId);
                } catch (Resources.NotFoundException e) {
                    throw new IllegalStateException("could not find string with ID " + stringId, e);
                }
            }
            return view.getResources().getString(stringId).equals(view.getHint());
        }
    };
}

matchers에 대한 자세한 내용은 다음을 참조하십시오.

http://hamcrest.org/

https://developer.android.com/reference/android/support/test/espresso/matcher/ViewMatchers.html

전반적인 에스프레소

설치 에스프레소 :

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'

ViewMatchers - Matcher<? super View> 를 구현하는 객체의 콜렉션 Matcher<? super View> 인터페이스. 하나 이상의 뷰를 onView 메서드에 전달하여 현재 뷰 계층 구조 내에서 뷰를 찾을 수 있습니다.

ViewActions - ViewInteraction.perform() 메서드에 전달할 수있는 ViewActions 컬렉션입니다 (예 : click() ).

ViewAssertions - ViewInteraction.check() 메서드를 전달할 수있는 ViewAssertions 컬렉션입니다. 대부분의 경우, Match 매서를 사용하여 현재 선택된보기의 상태를 표시합니다.


구글 에스프레소 치트 시트

여기에 이미지 설명을 입력하십시오.


EditText에서 텍스트 입력

onView(withId(R.id.edt_name)).perform(typeText("XYZ"));
        closeSoftKeyboard();

보기를 클릭하십시오.

 onView(withId(R.id.btn_id)).perform(click());

확인보기가 표시됩니다.

 onView(withId(R.id.edt_pan_number)).check(ViewAssertions.matches((isDisplayed())));

테스트 스위트에서 테스트 클래스 모음 그룹화

스위트를 정의하는 인스트루먼트 된 단위 테스트의 실행을 구성 할 수 있습니다.

/**
 * Runs all unit tests.
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({MyTest1.class , 
         MyTest2.class, 
         MyTest3.class})
public class AndroidTestSuite {}

그런 다음 AndroidStudio에서 gradle로 실행하거나 다음과 같은 새 구성을 설정할 수 있습니다.

여기에 이미지 설명을 입력하십시오.

테스트 스위트는 중첩 될 수 있습니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow