¿Android Espresso está mal configurado o no funciona de manera estable?

He estado implementando la prueba de Android espresso durante una semana. Lo que es real es implementar la llamada al servidor y esperarla con espresso. Esto se llama llamada Idle Resourse, y tenemos que seguir reglas, que son bastante directas para la universidad. En realidad, encontré la solución, pero el resultado es estremecedor: solo tengo éxito si comento líneas

Espresso.onView(ViewMatchers.withId(R.id.email)).perform(ViewActions.typeText("some shit"));
Espresso.onView(ViewMatchers.withId(R.id.password)).perform(ViewActions.typeText("123"));

y reemplazándolos con "huck":

final EditText email = (EditText) act.findViewById(R.id.email);
        final EditText password = (EditText) act.findViewById(R.id.password);
        getInstrumentation().runOnMainSync(new Runnable() {
            public void run() {
                email.setText("Engineer");
                password.setText("2342");
            }
        });

... antes de hacer clic en el botón que inicia una nueva actividad después de una llamada emulada al servidor. Estos son mis archivos completos: build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "shoppinglist.kizema.anton.testappespresso"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    packagingOptions {
        exclude 'LICENSE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/ASL2.0'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/DEPENDENCIES'
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

    // App's dependencies, including test
    compile 'com.android.support:support-annotations:21.0.3'

    // Testing-only dependencies
    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
}

LoginActivity (Primera actividad):

//set up initial listener
private void initLoginHelper(){
    loginHelper = new Server() {
        @Override
        public void login(String email, String code, String phone, String password, boolean loginByPhoneNumber) {
            //ask server
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //done
            Intent intent = new Intent(LoginActivity.this, SecondActivity.class);
            startActivityForResult(intent, 0);
        }
    };
}

//onButtonClick handler
public void btnLogInSuka(View v) {
    performLogin();
}
void performLogin() {
    new Thread(new Runnable() {
        @Override
        public void run() {
                loginHelper.login(emailParam,codeParam,phoneParam,passwordParam,false);
        }
    }).start();
}

Y AplicationTest.java (pruebas de espresso): @LargeTest public class ApplicationTest extiende ActivityInstrumentationTestCase2 {

public ApplicationTest() {
    super(LoginActivity.class);
}

CountingIdlingResource idleRes;

@Override
public void setUp() throws Exception {
    super.setUp();
    getActivity();

    idleRes = new CountingIdlingResource("server");
    Espresso.registerIdlingResources(idleRes);
}

public void testSample(){
    final LoginActivity act = (LoginActivity) getCurrentActivity();
    Server aHelper = act.getUserHelper();

    MyUserHelperExternalIdleRes helper2 = new MyUserHelperExternalIdleRes(idleRes, aHelper);
    act.setUserHelper(helper2);


    //if comment this and uncomment next two lines we receive PerformException
    final EditText email = (EditText) act.findViewById(R.id.email);
    final EditText password = (EditText) act.findViewById(R.id.password);
    getInstrumentation().runOnMainSync(new Runnable() {
        public void run() {
            email.setText("Engineer");
            password.setText("2342");
        }
    });

//        Espresso.onView(ViewMatchers.withId(R.id.email)).perform(ViewActions.typeText("some shit"));
//        Espresso.onView(ViewMatchers.withId(R.id.password)).perform(ViewActions.typeText("123"));

    Espresso.closeSoftKeyboard();
    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).perform(ViewActions.click());
    Espresso.onView(ViewMatchers.withId(R.id.secondActivityOpened)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
    Espresso.pressBack();

    Espresso.closeSoftKeyboard();
    Espresso.onView(ViewMatchers.withId(R.id.btnLogIn)).perform(ViewActions.click());
}

Activity getCurrentActivity() {
    getInstrumentation().waitForIdleSync();
    final Activity[] activity = new Activity[1];
    try {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                java.util.Collection<Activity> activites = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
                activity[0] = Iterables.getOnlyElement(activites);
            }});
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    return activity[0];
}

class MyUserHelperExternalIdleRes implements Server {
    private Server aHelper;
    private CountingIdlingResource udleRes;

    public MyUserHelperExternalIdleRes(CountingIdlingResource udleRes, Server aHelper) {
        this.aHelper = aHelper;
        this.udleRes = udleRes;
    }

    @Override
    public void login(String email, String code, String phone, String password, boolean loginByPhoneNumber) {

        udleRes.increment();
        try {
            aHelper.login(email,code, phone,password,loginByPhoneNumber);
        } finally {
            udleRes.decrement();
        }
    }
}

}

Entonces, si hacemos una operación básica de espresso: Espresso.onView (ViewMatchers.withId (R.id.password)). Perform (ViewActions.typeText ("123"));

Recibimos PerformException: no se puede encontrar el botón por id. Si hacemos un huck, (con la configuración de Runnable en el hilo de la interfaz de usuario), tenemos éxito con esta demostración simple. En mi aplicación principal hay otros errores con espresso (el "huck" escrito anteriormente no funcionó, recibimos el mismo mistke). Seguramente estoy teniendo un error muy complicado, supongo que algo con la configuración del proyecto (espresso) está mal: soy muy malo con gradle. Ayúdame con esto, o proporciona un enlace a la aplicación de muestra de Android Studio con pruebas de espresso (no encontré ninguna, todas las aplicaciones están mal configuradas (sin gradle), y después de importarlas a Android Studio, no puedo iniciarlas con

gradlew connectedAndroidTest

Respuestas a la pregunta(1)

Su respuesta a la pregunta