????????
// Android JUnit Runner
androidTestCompile 'com.android.support.test:runner:0.5'
// JUnit4 Rules
androidTestCompile 'com.android.support.test:rules:0.5'
 //?Щ??????????????????????????????????? espresso-contrib ?? exclude????
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'?? {
        exclude group: 'com.android.support'?? module: 'support-annotations'
}
//????????? defaultConfig ??????
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
????????????????????????
@RunWith(AndroidJUnit4.class)
public class Test {...}
????ActivityTestRule
????????????????????????????ActivityTestRule ???????????????launch???????activity
???????View
???????ViewMatcher.class??????????????????????View????????????Hello?????View??????????????
 onView(withText("Hello"));
???????????????????View?????Id???????view
onView(withId(R.id.hello));
???????ж???????????????????Matchers.class??allof()?????????????????£?
onView(allOf(withText("Hello") ??withId(R.id.hello)));
??????View????Щ????
??????View??????????????????? onView(...).perform();
??????onView????????View??????perform()???????в???????????View??
onView(withId(R.id.hello)).perform(click());
???????????ж???????????perform????
onView(withId(R.id.hello)).perform(click()??clearText());
???????View?????????????
???????check()?????????View??????????????? onView(...).check();
???????????View?????????????Hello??
onView(withId(R.id.hello)).check(matches(withText("Hello")));
??????????????????????????

????????
????1???ж????View?治????????????boolen
//Espresso??????????????????????????????????????????try catch
try {
        onView(withText("my button")).check(matches(isDisplayed()));
        //view is displayed logic
    } catch (NoMatchingViewException e) {
        //view not displayed logic
    }??
??????2????????Activity????????
Espresso.pressBack();
????3????2?????????View?????????????????????View
public static  <T> Matcher<T> firstFindView(final Matcher<T> matcher) {
        return new BaseMatcher<T>() {
            boolean isFirst = true;
            @Override
            public boolean matches(final Object item) {
                if (isFirst && matcher.matches(item)) {
                    isFirst = false;
                    return true;
                }
                return false;
            }
            @Override
            public void describeTo(final Description description) {
                description.appendText("should return first matching item");
            }
        };
    }
//???
onView(allOf(isDisplayed()??firstFindView(withText("Hello"))));
???????
????Intented??Intending
????????
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2'
???????????????Intents.init()?????????????Intents.release????????????RuleActivity??IntentsTestRule?????磺
????//?????ActivityTestRule????????????????????????????????
@Rule
public IntentsTestRule<ImageViewerActivity> mIntentsRule = new IntentsTestRule<>(ImageViewerActivity.class);
???????
????Intending??Mockito.when?????respondWith ???? thenReturn
 ActivityResult result = new ActivityResult(Activity.RESULT_OK?? resultData);
 intending(hasComponent(hasShortClassName(".ContactsActivity"))).respondWith(result);
Intenteded??Mockito.verify???????????Intent?????
intended(allOf(
                hasAction(Intent.ACTION_CALL)??
                hasData(INTENT_DATA_PHONE_NUMBER)??
                toPackage(PACKAGE_ANDROID_DIALER)));
????Espresso?????????????????Intent?????????????????????ε??????
Intent.setData <–> hasData
Intent.setAction <–> hasAction
Intent.setFlag <–> hasFlag
Intent.setComponent <–> hasComponent
????????????????????????
public void testLoginPass() {
    ActivityResult activityResult = new ActivityResult(Activity.RESULT_OK?? new Intent());
    Intents.init();
    intending(expectedIntent).respondWith(activityResult);
    onView(withId(R.id.button_login)).perform(click());
    intended(expectedIntent);
    Intents.release();
    onView(withId(R.id.button_login)).check(matches(withText(R.string.pass_login)));
}
???????????
??????????Activity??????????????Intent
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule =
            new ActivityTestRule<MainActivity>(MainActivity.class) {
                @Override
                protected Intent getActivityIntent() {
                    Context targetContext = InstrumentationRegistry.getInstrumentation()
                        .getTargetContext();
                    Intent result = new Intent(targetContext?? MainActivity.class);
                    result.putExtra("Name"?? "Value");
                    return result;
                }
            };
}
????????????ε???????????Intent?????
@Before
public void stubAllExternalIntents() {
   intending(not(isInternal())).respondWith(new ActivityResult(Activity.RESULT_OK?? null));
}
????Idling Resource
????????????????棬?????????????????????????????2??????
????????
compile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'
???????????????????????????????????????????????IDLE??????????Activity?м??????·??????????????л??
????//?????????????????????е???????????VisibleForTesting???????
@VisibleForTesting
public IdlingResource getIdlingResource() {
    return mIdlingResource;
}
???????
???????????????IdlingResource???app??????????????????д??????????
????getName()???????????idling resource????????????????????class.getName()
????isIdleNow()???????????idle??
????registerIdleTransitionCallback(..)?? ?????????
????????????????????????????IdlingResource???????????????Atom???????????????
??????????β????????????Espresso??????IdlingResource
@Before
public void registerIdlingResource() {
    mIdlingResource = mActivityRule.getActivity().getIdlingResource();
    Espresso.registerIdlingResources(mIdlingResource);
}
@After
public void unregisterIdlingResource() {
  if (mIdlingResource != null) {
    Espresso.unregisterIdlingResources(mIdlingResource);
  }
}
????RecyclerView
???????????RecyclerView?????????????????????
// Espresso-contrib for DatePicker?? RecyclerView?? Drawer actions?? Accessibility checks?? CountingIdlingResource
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
???????????????????????view?????????Щ????
onView(ViewMatchers.withId(R.id.recyclerView))
        .perform(RecyclerViewActions.actionOnItemAtPosition(ITEM_BELOW_THE_FOLD?? click()));
onView(ViewMatchers.withId(R.id.recyclerView))
                .perform(RecyclerViewActions.scrollToHolder(isInTheMiddle()));
onView(withId(R.id.recycleviews)).perform(RecyclerViewActions.actionOnHolderItem(new    
    CustomViewHolderMatcher(hasDescendant(withText("Name")))?? click()));
???????????????Щ?????
???????????????????????JUnit+Mock
???????е?Model??Presenter/ViewModel??Api??Utils?????public????
????Data?????getter??setter??toString??hashCode???????????????????????????
????UI????
?????????View??????????set data???text?????????????????????????????click??????????????????????touch?????????????
????Activity??????????????view????????????????????????????????????????????intent??????
??????????????????????onTouch?????view???????λ???????????????????